springboot的文件上传比较简单
一、使用默认的Resolver:StandardServletMultipartResolver
controller
package com.mydemo.webdemo.controller; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/") public class FileUploadController { private Logger logger = LoggerFactory.getLogger(FileUploadController.class); @Value("${upload.file.savepath:/tmp}") private String savePath; @RequestMapping("/toupload") public ModelAndView toWelcome() { ModelAndView mav = new ModelAndView(); mav.setViewName("fileupload"); mav.addObject("time", new Date()); return mav; } /** * 使用model传值 * * @param uploadFile * @param model * @return */ @PostMapping("/uploadone") public String uploadSingleFile(@RequestParam("uploadFile") MultipartFile uploadFile, Model model) { List<MultipartFile> uploadFileList = new ArrayList<>(); logger.info(uploadFile.toString()); try { uploadFileList.add(uploadFile); String result = saveFile(uploadFileList); model.addAttribute("msg", result); } catch (Exception e) { model.addAttribute("msg", "Upload failed"); e.printStackTrace(); } return "uploadResult"; } /** * 使用ModelAndView页面跳转和传值 * * @param uploadFile * @return */ @PostMapping("/uploadmore") public ModelAndView uploadMoreFile(@RequestParam("uploadFile") MultipartFile[] uploadFile) { ModelAndView mav = new ModelAndView(); List<MultipartFile> uploadFileList = new ArrayList<>(); try { uploadFileList.addAll(Arrays.asList(uploadFile)); String result = saveFile(uploadFileList); mav.addObject("msg", result); } catch (Exception e) { mav.addObject("msg", "Upload failed"); e.printStackTrace(); } mav.setViewName("uploadResult"); return mav; } private String saveFile(List<MultipartFile> uploadFileList) { int successNum = 0; for (MultipartFile uploadFile : uploadFileList) { InputStream is = null; FileOutputStream fos = null; try { String fileName = uploadFile.getOriginalFilename(); is = uploadFile.getInputStream(); fos = new FileOutputStream(savePath + File.separator + fileName); int len = 0; byte[] b = new byte[1024]; while ((len = (is.read(b))) != -1) { fos.write(b, 0, len); } successNum += 1; } catch (Exception e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } } if (successNum == 0) { return "Upload failed"; } else if (successNum == uploadFileList.size()) { return "Upload success"; } else { return "Partial upload success"; } } }
src/main/resources/templates/fileupload.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Current time:<span th:text=${time} /><br />
<h5>===========================分割线=============================</h5>
<form id = "uploadone" action="${request}" th:action="@{/uploadone}" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" /><br />
<input type="submit" value="UploadOne">
</form>
<h5>===========================分割线=============================</h5>
<form id = "uploadmore" action="${request}" th:action="@{/uploadmore}" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" /><br />
<input type="file" name="uploadFile" /><br />
<input type="file" name="uploadFile" /><br />
<input type="submit" value="UploadMore">
</form>
</body>
</html>
src/main/resources/templates/uploadResult.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <span th:text=${msg}/> </body> </html>
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <groupId>com.mydemo.webdemo</groupId> <artifactId>fileuploaddemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>fileuploaddemo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties
spring.mvc.servlet.load-on-startup=1 server.servlet.context-path=/uploaddemo upload.file.savepath=D:/upload ## per file size, 500M spring.servlet.multipart.max-file-size=524288000 ## max file size in one request, 600M spring.servlet.multipart.max-request-size=629145600 ## in memory size after write to disk, 10M spring.servlet.multipart.file-size-threshold=10240
二、使用CommonsMultipartResolver
在第一步操作的基础上,注册multipartResolver的bean为CommonsMultipartResolver
package com.mydemo.webdemo.custombean; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.multipart.commons.CommonsMultipartResolver; @Component public class CustomBean { @Bean(name = "multipartResolver") public CommonsMultipartResolver getMultipartResolver() { CommonsMultipartResolver resolver = new CommonsMultipartResolver(); resolver.setDefaultEncoding("UTF-8");// default ISO-8859-1 resolver.setMaxInMemorySize(10240);// default 10240 ,单位bytes resolver.setMaxUploadSize(1024*1024*600);// default -1 ,无限制,单位bytes resolver.setMaxUploadSizePerFile(1024*1024*500);// default -1 ,无限制,单位bytes return resolver; } }
pom.xml文件中需要添加commons-fileupload依赖
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
application.properties配置中去掉上述包含multipart的三个参数,保留如下
spring.mvc.servlet.load-on-startup=1 server.servlet.context-path=/uploaddemo upload.file.savepath=D:/upload
三、文件下载
在上述基础上,添加下载Controller
package com.mydemo.webdemo.controller; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class DownloadController { private Logger logger = LoggerFactory.getLogger(FileUploadController.class); @RequestMapping("/download") @ResponseBody public void download(HttpServletRequest request, HttpServletResponse response) { String fileName = request.getParameter("fileName"); String filePah = "D:/upload" + File.separator + fileName; // 自动判断下载文件类型 response.setContentType("multipart/form-data"); // 设置文件名称 response.setHeader("Content-Disposition", "attachment;fileName=" + fileName); FileInputStream fis = null; OutputStream out = null; try { fis = new FileInputStream(filePah); out = response.getOutputStream(); byte[] b = new byte[1024]; int len; while ((len = fis.read(b)) != -1) { out.write(b, 0, len); } } catch (IOException e) { logger.error("", e); } finally { try { if (fis != null) { fis.close(); } if (out != null) { out.close(); } } catch (IOException e) { logger.error("", e); } } } }
D:uploadupload.tar文件存在,则可通过如下链接下载该文件
http://localhost:8080/uploaddemo/download?fileName=upload.tar
遗留问题:
1、当上传文件大小超过了文件限制大小后,不能将异常信息传递给前端,比如本例中单个文件大小设置为500M,上传大于500M的单个文件,出现异常,但不能将该异常信息传递给前端正常显示