SpringBoot ~ 文件上传
文件上传
SpringBoot中对文件上传做了简化,使文件上传变得非常方便,以下分享前后端分离的情况下单文件上传与多文件上传的写法。
-
依赖添加(pom.xml)(基本依赖)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> -
配置
Java中文件上传涉及2个组件,其一是基于commons-fileupload的CommonsMutipartResolver来处理multipart请求,其二是基于Servlet 3.0的StandardServletMultipartResolver来处理multipart请求。Tomcat7开始支持Servlet 3.0,所以SpringBoot内嵌了Tomcat,SpringBoot提供的文件上传自动化配置类MultipartAutoConfiguration,如果开发者未提供MultipartResolver,默认也采用StandardServletMultipartResolver组件,所以SpringBoot文件上传可以做到零配置。
-
application.properties配置(非必需)
#配置文件上传 #是否开启文件上传支持,默认true spring.servlet.multipart.enabled=true #文件写入磁盘的阈值,默认为0 spring.servlet.multipart.file-size-threshold=0 #上传文件的临时保存位置 spring.servlet.multipart.location=D:\\data #上传的单个文件的最大大小,默认1MB spring.servlet.multipart.max-file-size=100MB #多文件上传时,文件的总大小,默认10MB spring.servlet.multipart.max-request-size=100MB #表示文件是否延迟解析,默认为false spring.servlet.multipart.resolve-lazily=false
-
-
Controller
package cn.wsyjlly.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @author wsyjlly * @create 2019.06.13 - 17:23 **/ @RestController public class FileUploadController { private String fomartDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); private final String UPLOAD_PATH = "/uploadFiles/"; private final Integer SUCCESS = 1; private final Integer FAILURE = 0; private Logger logger = LoggerFactory.getLogger(getClass()); /* * 单文件上传 * */ @PostMapping("/upload") public ModelMap upload(MultipartFile uploadFile, HttpServletRequest request) { ModelMap map = new ModelMap(); if (uploadFile == null){ map.addAttribute("status",FAILURE); map.addAttribute("message","未选择文件"); return map; } File folder = getRootPath(); logger.debug("文件夹路径:"+folder.getAbsolutePath()); String originalFilename = uploadFile.getOriginalFilename(); logger.debug("文件原名:"+originalFilename); String newName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length()); try { uploadFile.transferTo(new File(folder,newName)); String filePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + UPLOAD_PATH + fomartDate+"/" + newName; logger.debug("文件访问路径:"+filePath); map.addAttribute("filePath",filePath); map.addAttribute("status",SUCCESS); return map; } catch (IOException e) { e.printStackTrace(); } map.addAttribute("status",FAILURE); return map; } /* * 多文件上传 * */ @PostMapping("/uploads") public ModelMap uploads(MultipartFile[] uploadFiles, HttpServletRequest request) { ModelMap map = new ModelMap(); logger.debug("文件个数:"+uploadFiles.length); //String realPath = ResourceUtils.getURL("classpath:").getPath()+UPLOAD_PATH; File folder = getRootPath(); HashMap<String, Map> fileListUploadStatus = new HashMap<>(); for (MultipartFile file:uploadFiles){ HashMap<String, Object> item = new HashMap<>(); String originalFilename = file.getOriginalFilename(); System.out.println("————————————————————————————————"); logger.debug("————————————————————————————————"); logger.debug("文件原名:"+originalFilename); logger.debug("文件大小:"+file.getSize()); logger.debug("文件类型:"+file.getContentType()); String newName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length()); try { file.transferTo(new File(folder,newName)); String filePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + UPLOAD_PATH + fomartDate+"/" + newName; logger.debug("访问地址:"+filePath); logger.debug("地址文件名:"+newName); item.put("isUpload",true); item.put("url",filePath); fileListUploadStatus.put(originalFilename,item); } catch (IOException e) { item.put("isUpload",false); item.put("url",""); fileListUploadStatus.put(originalFilename,item); e.printStackTrace(); } } map.addAttribute("resultList",fileListUploadStatus); return map; } private File getRootPath(){ File file = new File(System.getProperty("user.dir")+UPLOAD_PATH); if(!file.exists()){//如果文件夹不存在 file.mkdirs();//创建文件夹 } String rootPath = file.getAbsolutePath(); File folder = new File(rootPath+'/' + fomartDate); if (!folder.isDirectory()){ folder.mkdirs(); } return folder; } } -
静态资源访问路径配置
如果上传资源需要被访问,则须配置上传文件路径添加静态资源访问路径。
注意:在Linux系统和window系统中相对于当前运行位置的盘的根路径都可表示为 ‘/’
静态资源文件路径分为两种:
- 相对路径(相对于classes的路径)即:'classpath:'
- 绝对路径:文件系统路径,配置文件系统静态资源路径时须添加前缀:'file:'
/** * @author wsyjlly * @create 2019.06.12 - 16:17 **/ @Configuration public class WebMvcConfig implements WebMvcConfigurer { private Logger logger = LoggerFactory.getLogger(getClass()); /* * 配置静态资源过滤策略 * 将静态资源路径映射为访问路径 * */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/"); String uploadPath = new File(System.getProperty("user.dir"),"uploadFiles") .getAbsolutePath().replaceAll("\\\\","/")+"/"; registry.addResourceHandler("/uploadFiles/**"). addResourceLocations("file:"+uploadPath); logger.info("上传文件路径映射:/uploadFiles/** ————>> "+uploadPath); } }