????????基于JavaWeb实战开发中的Servlet实现文件上传和下载的操作,org.springframework:spring-webmvc依赖为SpringMVC提供了multipart解析器和MultipartFile的一些文件操作方法,使文件上传变得更加方便简单。
一搭建SpringMVC项目环境(IDEA)
首先我们要创建一个Maven工程,然后在Maven的pom.xml配置文件中把Maven项目打成war包,即我们所说的web工程。接着添加我们本工程所需要的依赖如下:
?????????????????????????????????????????????????????????? ?
之后我们便可以在该Maven工程下创建src/main/webapp,并对webapp进行配置得到webapp/WEB-INF/web.xml,然后就可以在web.xml文件中配置我们的DispatcherServlet中央处理器。init-param是我们将来要加载的配置文件,缓冲区是将来文件上传时缓冲的区域,需要手动在盘符底下创建文件。配置如下:
??????????????????????????????????????
?因为将来我们需要用到SpringMVC容器中的bean对象,因此我们要在resource包底下新建一个xml文件我把他命名为spring-servlet.xml,然后我们配置我们的包扫描,把注解对象拿出来用。
??????????????????????
?配置如下:
<context:component-scan base-package="com.qf.hjp.demo"/>
<mvc:annotation-driven/>
?这里还需要文件上传解析器,注意,这个bean的名字一定要有,而且id必须叫multipartResolver。接下来在配置一个东西允许加载静态文件。
<bean class="org.springframework.web.multipart.support.StandardServletMultipartResolver" id="multipartResolver"/>
<!--允许加载静态资源-->
<mvc:resources mapping="/**" location="/"/>
到此为止,我们的项目文件算是搭建好了。
二实现文件上传功能
? ? ? ? 项目环境搭建好之后,我们在com/qf/hjp/demo创建一个测试类我们叫做FileUpload。
@RestController
public class FileUpload(){
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
@PostMapping("/upload")
public String upload(MultipartFile file, String username, HttpServletRequest req){
//这里测试文件上传能不能携带除file以外的text参数
System.out.println("username = " + username);
//1.上传文件的保存路径
//按日期对上传文件分类储存 /2022/01/12/
String format = sdf.format(new Date());
//获取项目的运行时目录
String realPath = req.getServletContext().getRealPath("/img") + format;
File folder = new File(realPath);
if (!folder.exists()){
folder.mkdirs();
}
//2.文件名
//获取旧的文件名
String oldName = file.getOriginalFilename();
//生成新的文件名
String newName = UUID.randomUUID().toString()+oldName.substring(oldName.lastIndexOf("."));
//保存文件
try {
file.transferTo(new File(folder,newName));
String url = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getContextPath() + "/img" + format + newName;
//文件上传成功返回URL地址
return url;
} catch (IOException e) {
e.printStackTrace();
}
//失败则返回error响应在前端页面上
return "error";
}
}
最后写一个简单的html页面实现文件上传:
<body>
<form action="/int/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="text" name="username">
<input type="submit" value="提交">
</form>
</body>
注意:这里必须要加上multipart/form-data,原因在servlet的文章中有详细解释。
????????最后的结果是客户端跳转返回一个URL地址,复制URL地址到地址栏中访问能够查看我们上传的图片。username也可以成功打印在控制台上。
三实现文件的下载功能
/**
* 文件下载
* http://localhost:8081/int/download/2022/01/12/15f5d06f-9872-4445-8f85-e4ff95493fe6.png
* resp.addHeader("content-disposition", "attachment;filename="+new String("图片".getBytes("UTF-8"),"ISO-8859-1"));
*/
@GetMapping("/download/{year}/{month}/{day}/{filename}")
public void download(@PathVariable String year, @PathVariable String month, @PathVariable String day, @PathVariable String filename, HttpServletRequest req, HttpServletResponse resp) throws IOException {
//文件下载,只需要在文件访问的基础上,加上响应头信息即可
//文件名如果是中文,注意转码
resp.addHeader("content-disposition","attachment;filename="+filename);
//获取文件绝对路径
String realPath = req.getServletContext().getRealPath("/img") + File.separator + year + File.separator + month + File.separator + day + File.separator + filename;
//System.out.println("realPath = " + realPath);
//获取字节流
FileInputStream fis = new FileInputStream(realPath);
ServletOutputStream os = resp.getOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = fis.read(bytes))!=-1){
os.write(bytes,0,len);
}
os.flush();
}
/**
* 文件下载方式二
* @return
*/
@GetMapping("/download2")
public ResponseEntity<byte[]> download2(String filename) throws IOException {
//要下载的文件位于该目录下
String folder = "G:\\千锋Java2108\\File\\File1";
String filePath = folder + File.separator + filename;
System.out.println("filePath = " + filePath);
//输入流,读取文件
FileInputStream fis = new FileInputStream(filePath);
//输出流,将来读进来的文件存入一个 byte 数组中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = fis.read(bytes))!=-1){
baos.write(bytes,0,len);
}
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment",new String(filename.getBytes("UTF-8"),"ISO-8859-1"));
//1.响应体,就是 一个byte 数组
//2.响应头
//3.http 响应状态码
return new ResponseEntity<>(baos.toByteArray(),headers, HttpStatus.CREATED);
}
|