ToB企服应用市场:ToB评测及商务社交产业平台

标题: 11、SpringMVC之文件下载和上传 [打印本页]

作者: 泉缘泉    时间: 2023-12-5 23:56
标题: 11、SpringMVC之文件下载和上传
创建名为spring_mvc_file的新module,过程参考9.1节和9.5节
11.1、文件下载

11.1.1、创建图片目录并放置图片


11.1.2、页面请求示例

  1. <a th:target="_blank" href="https://www.cnblogs.com/@{/test/down}">下载图片</a>
复制代码
11.1.3、控制器方法示例

  1. package online.liaojy.controller;
  2. import org.springframework.http.HttpHeaders;
  3. import org.springframework.http.HttpStatus;
  4. import org.springframework.http.ResponseEntity;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.util.MultiValueMap;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import javax.servlet.ServletContext;
  9. import javax.servlet.http.HttpSession;
  10. import java.io.*;
  11. /**
  12. * @author liaojy
  13. * @date 2023/11/2 - 20:50
  14. */
  15. @Controller
  16. public class FileDownloadController {
  17.     // ResponseEntity 可以作为控制器方法的返回值,表示响应到浏览器的完整响应报文(包含响应体、响应体和响应状态码)
  18.     @RequestMapping("/test/down")
  19.     public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
  20.         //获取ServletContext对象
  21.         ServletContext servletContext = session.getServletContext();
  22.         //获取服务器中工程的真实路径
  23.         String realPath = servletContext.getRealPath("");
  24.         //拼接工程路径和文件路径
  25.         //File.pathSeparator 表示文件路径分隔符,其能自动适应不同系统的路径分隔符(例如Windows的分隔符是\,Linux的分隔符是/)
  26.         realPath = realPath + File.separator + "img" + File.separator + "Windows.jpg";
  27.         //创建输入流
  28.         InputStream is = new FileInputStream(realPath);
  29.         //创建字节数组作为响应报文的响应体,is.available() 用于获取输入流所对应的文件的字节数
  30.         byte[] bytes = new byte[is.available()];
  31.         //将流读到字节数组中
  32.         is.read(bytes);
  33.         //创建HttpHeaders对象设置响应头信息
  34.         MultiValueMap<String, String> headers = new HttpHeaders();
  35.         //设置下载方式以及下载文件的名字
  36.         //请求头的键不区分大小写,Content Disposition头用来强制浏览器下载文件,而不是在浏览器中显示
  37.         //attachment表示以附件形式下载,即在下载时有提示信息
  38.         //filename表示下载的文件的名字
  39.         headers.add("Content-Disposition", "attachment;filename=Win10.jpg");
  40.         //设置响应状态码
  41.         HttpStatus statusCode = HttpStatus.OK;
  42.         //创建ResponseEntity对象
  43.         ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(bytes, headers, statusCode);
  44.         //关闭输入流
  45.         is.close();
  46.         return responseEntity;
  47.     }
  48. }
复制代码
11.1.4、测试效果



11.2、文件上传

11.2.1、页面请求示例

  1. <form th:action="@{/test/up}" method="post" enctype="multipart/form-data">
  2.    
  3.     图片:<input type="file" name="photo">
  4.    
  5.     <input type="submit" value="上传图片">
  6. </form>
复制代码
11.2.2、引入依赖

  1.         
  2.         <dependency>
  3.             <groupId>commons-fileupload</groupId>
  4.             <artifactId>commons-fileupload</artifactId>
  5.             <version>1.3.1</version>
  6.         </dependency>
复制代码
11.2.3、配置文件上传解析器


注意:springmvc 根据bean的id来获取文件解析器,因此必须设置 id 属性,且属性值必须为 multipartResolver
  1.    
  2.    
  3.    
  4.     <bean id="multipartResolver" >
  5.         
  6.         
  7.         
  8.         
  9.         
  10.         
  11.         
  12.         
  13.         
  14.         
  15.         
  16.         
  17.     </bean>
复制代码
11.2.4、控制器方法示例

  1. package online.liaojy.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.multipart.MultipartFile;
  5. import javax.servlet.ServletContext;
  6. import javax.servlet.http.HttpSession;
  7. import java.io.File;
  8. import java.io.IOException;
  9. /**
  10. * @author liaojy
  11. * @date 2023/11/5 - 18:06
  12. */
  13. @Controller
  14. public class FileUploadController {
  15.     @RequestMapping("/test/up")
  16.     public String testUp(MultipartFile photo, HttpSession session) throws IOException {
  17.         // 获取上传的文件的文件名
  18.         String originalFilename = photo.getOriginalFilename();
  19.         // 获取ServletContext对象
  20.         ServletContext servletContext = session.getServletContext();
  21.         // 获取服务器中当前工程下photo目录的真实路径
  22.         String photoPath = servletContext.getRealPath("photo");
  23.         // 创建photoPath所对应的file对象
  24.         File file = new File(photoPath);
  25.         // 判断file所对应目录是否存在
  26.         if (!file.exists()){
  27.             // file所对应目录不存在,则创建该目录
  28.             file.mkdir();
  29.         }
  30.         // 拼接目录路径和文件名为最终路径
  31.         String finalPath = photoPath + File.separator + originalFilename;
  32.         // 上传文件
  33.         photo.transferTo(new File(finalPath));
  34.         return "success";
  35.     }
  36. }
复制代码
11.2.5、测试效果






11.3、文件上传的重名问题

11.3.1、问题描述

如果上传了同名的文件,那新的文件就会覆盖旧的文件;
因此需要通过一个机制,保证上传后的文件名的不会和新上传的文件名重复;
通常,可以使用uuid或时间戳,替换原来的文件名,从而保证文件名的唯一性。
11.3.2、解决方式

  1.         // 获取上传的文件的后缀名
  2.         String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
  3.         // 使用uuid生成的字符串和上传文件的后缀名,拼接成一个新的文件名
  4.         String fileName = UUID.randomUUID().toString() + suffixName;
复制代码
  1.         // 拼接目录路径和新的文件名为最终路径
  2.         String finalPath = photoPath + File.separator + fileName;
复制代码
11.3.3、测试效果







免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4