1、文件上傳
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); } }