目录
这次的笔记使用的模块是 SpringMVC-demo4
1、文件下载
使用 ResponseEntity 实现文件下载的功能
① 在 src/main/webapp/static/img 下放一张图片,名字就叫 a.jpg 吧
② 由于往项目中添加了静态资源,需要重新在 Maven 中重新打包,服务器才会有相关资源
③ 在 src/main/webapp/WEB-INF/templates 下新建 file.html,用作存放下载和上传链接的页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>测试文件上传和下载</title>
</head>
<body>
<a th:href="@{/testDown}">下载a.jpg</a>
</body>
</html>
④ 为了能够跳转到 file.html 页面,在 springMVC.xml 中添加视图控制器
<mvc:view-controller path="/file" view-name="file"></mvc:view-controller>
⑤ 创建 FileUpAndDownController 控制器类,用来存放上传和下载所需的控制器方法,并添加下载所需的方法
@Controller
public class FileUpAndDownController {
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径,这里的真实路径是target文件夹下的路径
String realPath = servletContext.getRealPath("/static/img/a.jpg");
System.out.println(realPath); //这里输出真实路径用作测试
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
//is.available()返回对应输入流的所有字节数
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字,这里只有文件名filename的值可以根据需要更改,其他不用更改,attachment表示以附件的方式下载
headers.add("Content-Disposition", "attachment;filename=a.jpg");
//设置响应状态码,就是 200
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
//关闭输入流
is.close();
return responseEntity;
}
}
⑥ 运行测试,打开 http://localhost:8080/SpringMVC_demo4/file 页面,点击测试链接进行测试,可以看到浏览器直接新建了一个下载任务,下载后就可以在对应目录找到资源
2、文件上传
文件上传要求 form 表单的请求方式必须为 post ,并且添加属性enctype="multipart/form-data"
SpringMVC中将上传的文件封装到 MultipartFile 对象中,通过此对象可以获取文件相关信息
① 首先在 file.html 页面添加测试的表单
<!-- 文件上传 -->
<!--
enctype属性规定在发送到服务器之前应该如何对表单数据进行编码的
默认值是application/x-www-form-urlencoded,就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值)。
multipart/form-data:不对字符编码(也就是二进制)。在使用包含文件上传控件的表单时,必须使用该值。
-->
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
头像:<input type="file" name="photo"><br>
<input type="submit" value="上传">
</form>
② 在 pom.xml 添加依赖
<!-- 文件上传的依赖 https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
③ 在 springMVC.xml 配置文件中添加配置
<!-- 配置文件上传解析器,将上传的文件封装为MultipartFile -->
<!-- id必须为multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
④ 在 FileUpAndDownController 类中添加方法
//文件上传
@RequestMapping("/testUp")
public String testUp(MultipartFile photo){
System.out.println("getName = " + photo.getName());
System.out.println("getOriginalFilename = " + photo.getOriginalFilename());
return "success";
}
⑤ 运行测试,发现页面成功跳转,查看控制台的输出
从而得知 getName() 是获取 MultipartFile 类型的属性名,getOriginalFilename() 是获取上传的文件的文件名
⑥ 修改文件上传的控制器方法
//文件上传
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
//System.out.println("getName = " + photo.getName()); //getName = photo
//System.out.println("getOriginalFilename = " + photo.getOriginalFilename()); //getOriginalFilename = a.jpg
// 获取文件名
String fileName = photo.getOriginalFilename();
// 获取文件存放路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
// 判断photoPath对应路径是否存在
if(!file.exists()){
// 若不存在,则创建目录
file.mkdir();
}
// 将photoPath对应路径加上分隔符加上文件名形参最终路径。File.separator就是分隔符
String finalPath = photoPath + File.separator + fileName;
// 传输文件到指定路径下
photo.transferTo(new File(finalPath));
return "success";
}
⑦ 运行测试,在 target 目录下会生成 photo 目录,存放上传的照片
3、文件上传的文件名重复问题
使用 UUID 为文件命名
//文件上传
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
//System.out.println("getName = " + photo.getName()); //getName = photo
//System.out.println("getOriginalFilename = " + photo.getOriginalFilename()); //getOriginalFilename = a.jpg
// 获取上传的文件名
String fileName = photo.getOriginalFilename();
// 获取上传的文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
// 将UUID作为文件名
String uuid = UUID.randomUUID().toString();
// 将uuid和后缀名拼接后的结果作为最终文件名
fileName = uuid + suffixName;
// 获取文件存放路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
// 判断photoPath对应路径是否存在
if(!file.exists()){
// 若不存在,则创建目录
file.mkdir();
}
// 将photoPath对应路径加上分隔符加上文件名形参最终路径。File.separator就是分隔符
String finalPath = photoPath + File.separator + fileName;
// 传输文件到指定路径下
photo.transferTo(new File(finalPath));
return "success";
}