# 第十六章:文件上传和下载 ## 1.文件上传 ### 1.创建项目,导包 ```java org.springframework spring-web 4.3.6.RELEASE org.springframework spring-webmvc 4.3.6.RELEASE commons-io commons-io 2.5 commons-fileupload commons-fileupload 1.3.2 javax.servlet servlet-api 2.5 ``` ### 2.web.xml ```java springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc-config.xml 1 springmvc / ``` ### 3.springmvc-config.xml ```java ``` ### 4.创建fileUpload.jsp webapp下的jsp文件可以通过url直接访问 而WEB-INF下的js文件需要控制器中的方法返回才可以访问到 ```html Title
上传人: 请选择文件:
``` ### 5.创建success.jsp error.jsp ```html 上传失败 ``` ```html 上传成功 ``` ![image-20220517103654553](https://lsky.hhdxw.top/imghub/img/image-20220517103654553.png) ### 6.创建控制器 ```java package com.gzh.controller; /** * 文件上传 */ @Controller public class FileUploadController { /** * 执行文件上传 */ @RequestMapping("/fileUpload") public String handleFormUpload(@RequestParam("name") String name, @RequestParam("uploadfile") List uploadfile, HttpServletRequest request) { // 判断所上传文件是否存在 if (!uploadfile.isEmpty() && uploadfile.size() > 0) { //循环输出上传的文件 for (MultipartFile file : uploadfile) { // 获取上传文件的原始名称 String originalFilename = file.getOriginalFilename(); // 设置上传文件的保存地址目录 String dirPath = request.getSession().getServletContext().getRealPath("/upload/"); File filePath = new File(dirPath); // 如果保存文件的地址不存在,就先创建目录 if (!filePath.exists()) { filePath.mkdirs(); } // 使用UUID重新命名上传的文件名称(上传人_uuid_原始文件名称) String newFilename = name + "_" + UUID.randomUUID() + "_" + originalFilename; try { // 使用MultipartFile接口的方法完成文件上传到指定位置 file.transferTo(new File(dirPath + newFilename)); } catch (Exception e) { e.printStackTrace(); return "error"; } } // 跳转到成功页面 return "success"; } else { return "error"; } } } ``` ### 7.发布项目 ![image-20220517105222969](https://lsky.hhdxw.top/imghub/img/image-20220517105222969.png) ![image-20220517105211357](https://lsky.hhdxw.top/imghub/img/image-20220517105211357.png) ![image-20220517105334825](https://lsky.hhdxw.top/imghub/img/image-20220517105334825.png) ## 2.文件下载 ### 1.创建download.jsp ```html 下载页面 文件下载 "> 中文名称文件下载 ``` ### 2.添加控制器 下载文件的名字会产生乱码 ```java @RequestMapping("/download") public ResponseEntity fileDownload(HttpServletRequest request,String filename) throws Exception { // 指定要下载的文件所在路径 String path = request.getSession().getServletContext().getRealPath("/upload/"); // 创建该文件对象 File file = new File(path + File.separator + filename); // 设置响应头 HttpHeaders headers = new HttpHeaders(); // 通知浏览器以下载的方式打开文件 headers.setContentDispositionFormData("attachment", filename); // 定义以流的形式下载返回文件数据 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 使用Sring MVC框架的ResponseEntity对象封装返回下载数据 return new ResponseEntity(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK); } ``` 能保证下载的文件中文名字 ```java @RequestMapping("/download") public ResponseEntity fileDownload(HttpServletRequest request,String filename) throws Exception { // 指定要下载的文件所在路径 String path = request.getSession().getServletContext().getRealPath("/upload/"); // 创建该文件对象 File file = new File(path + File.separator + filename); // 对文件名编码,防止中文文件乱码 filename = this.getFilename(request, filename); // 设置响应头 HttpHeaders headers = new HttpHeaders(); // 通知浏览器以下载的方式打开文件 headers.setContentDispositionFormData("attachment", filename); // 定义以流的形式下载返回文件数据 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 使用Sring MVC框架的ResponseEntity对象封装返回下载数据 return new ResponseEntity(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK); } /** * 根据浏览器的不同进行编码设置,返回编码后的文件名 */ public String getFilename(HttpServletRequest request,String filename) throws Exception { // IE不同版本User-Agent中出现的关键词 String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"}; // 获取请求头代理信息 String userAgent = request.getHeader("User-Agent"); for (String keyWord : IEBrowserKeyWords) { if (userAgent.contains(keyWord)) { //IE内核浏览器,统一为UTF-8编码显示 return URLEncoder.encode(filename, "UTF-8"); } } //火狐等其它浏览器统一为ISO-8859-1编码显示 return new String(filename.getBytes("UTF-8"), "ISO-8859-1"); } ``` ### 3.发布项目 用第一个控制器,下载的文件不是中文名称 ![image-20220517112749837](https://lsky.hhdxw.top/imghub/img/image-20220517112749837.png) 用第二个控制器,下载的文件是中文名称 ![image-20220517113013424](https://lsky.hhdxw.top/imghub/img/image-20220517113013424.png)