SpringBoot ~ 文件上傳

1、文件上傳

SpringBoot中對文件上傳做了簡化,使文件上傳變得非常方便,以下分享前後端分離的情況下單文件上傳與多文件上傳的寫法。

  1. 依賴添加(pom.xml)(基本依賴)

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  2. 配置

    ​ Java中文件上傳涉及2個組件,其一是基於commons-fileupload的CommonsMutipartResolver來處理multipart請求,其二是基於Servlet 3.0的StandardServletMultipartResolver來處理multipart請求。Tomcat7開始支持Servlet 3.0,所以SpringBoot內嵌了Tomcat,SpringBoot提供的文件上傳自動化配置類MultipartAutoConfiguration,如果開發者未提供MultipartResolver,默認也採用StandardServletMultipartResolver組件,所以SpringBoot文件上傳可以做到零配置。

    1. 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
  3. 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;
        }
    }
  4. 靜態資源訪問路徑配置

    如果上傳資源需要被訪問,則須配置上傳文件路徑添加靜態資源訪問路徑。

    注意:在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);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章