SpringBoot 2.x (3):文件上傳


文件上傳有兩個要點

一是如何高效地上傳:使用MultipartFile替代FileOutputSteam

二是上傳文件的路徑問題的解決:使用路徑映射

文件路徑通常不在classpath,而是本地的一個固定路徑或者是一個文件服務器路徑

 

SpringBoot的路徑:

src/main/java:存放代碼

src/main/resources:存放資源

  static: 存放靜態文件:css、js、image (訪問方式 http://localhost:8080/js/main.js)

  templates:存放靜態頁面:html,jsp

  application.properties:配置文件

但是要注意:

比如我在static下新建index.html,那么就可以訪問localhost:8080/index.html看到頁面

如果在templates下新建index.html,那么訪問會顯示錯誤,除非在Controller中進行跳轉

如果想對默認靜態資源路徑進行修改,則在application.properties中配置:

spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 

這里默認的順序是先從/META-INF/resources中進行尋找,最后找到/public,可以在后邊自行添加

 

文件上傳不是老問題,這里就當是鞏固學習了

方式:MultipartFile file,源自SpringMVC

首先需要一個文件上傳的頁面

在static目錄下新建一個html頁面:

<!DOCTYPE html>
<html>
<head>
<title>文件上傳</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <form enctype="multipart/form-data" method="post" action="/upload">
        文件:<input type="file" name="head_img" /> 姓名:<input type="text"
            name="name" /> <input type="submit" value="上傳" />
    </form>
</body>
</html>

 

文件上傳成功否需要返回的應該是一個封裝的對象:

package org.dreamtech.springboot.domain;

import java.io.Serializable;

public class FileData implements Serializable {
    private static final long serialVersionUID = 8573440386723294606L;
    // 返回狀態碼:0失敗、1成功
    private int code;
    // 返回數據
    private Object data;
    // 錯誤信息
    private String errMsg;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    public FileData(int code, Object data) {
        super();
        this.code = code;
        this.data = data;
    }

    public FileData(int code, Object data, String errMsg) {
        super();
        this.code = code;
        this.data = data;
        this.errMsg = errMsg;
    }

}

 

處理文件上傳的Controller:

package org.dreamtech.springboot.controller;

import java.io.File;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.dreamtech.springboot.domain.FileData;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class FileController {
    private static final String FILE_PATH = "D:\\temp\\images\\";
    static {
        File file = new File(FILE_PATH);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    @RequestMapping("/upload")
    private FileData upload(@RequestParam("head_img") MultipartFile file, HttpServletRequest request) {
        if (file.isEmpty()) {
            return new FileData(0, null, "文件不能為空");
        }
        String name = request.getParameter("name");
        System.out.println("用戶名:" + name);
        String fileName = file.getOriginalFilename();
        System.out.println("文件名:" + fileName);
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        System.out.println("后綴名:" + suffixName);
        fileName = UUID.randomUUID() + suffixName;
        String path = FILE_PATH + fileName;
        File dest = new File(path);
        System.out.println("文件路徑:" + path);
        try {
            // transferTo文件保存方法效率很高
            file.transferTo(dest);
            System.out.println("文件上傳成功");
            return new FileData(1, fileName);
        } catch (Exception e) {
            e.printStackTrace();
            return new FileData(0, fileName, e.toString());
        }
    }
}

 

還有問題要處理,保存圖片的路徑不是項目路徑,而是本地的一個固定路徑,那么要如何通過URL訪問到圖片呢?

對路徑進行映射:比如我圖片保存在D:\temp\image,那么我們希望訪問localhost:8080/image/xxx.png得到圖片

可以修改Tomcat的配置文件,也可以按照下面的配置:

package org.dreamtech.springboot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebAppConfigurer implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/image/**").addResourceLocations("file:D:/temp/images/");
    }
}

 

還有一些細節問題不得忽略:對文件大小進行限制

package org.dreamtech.springboot.config;

import javax.servlet.MultipartConfigElement;

import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.unit.DataSize;

@Configuration
public class FileSizeConfigurer {
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        // 單個文件最大10MB
        factory.setMaxFileSize(DataSize.ofMegabytes(10L));
        /// 設置總上傳數據總大小10GB
        factory.setMaxRequestSize(DataSize.ofGigabytes(10L));
        return factory.createMultipartConfig();
    }
}

 

打包后的項目如何處理文件上傳呢?

順便記錄SpringBoot打包的坑,mvn clean package運行沒有問題,但是不太方便

於是eclipse中run as maven install,但是會報錯,根本原因是沒有配置JDK,配置的是JRE:

解決:https://blog.csdn.net/lslk9898/article/details/73836745

 

圖片量不大的時候,我們可以用自己的服務器自行處理,

如果圖片量很多,可以采用圖片服務器,自己用Nginx搭建或者阿里OSS等等


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM