文件上傳有兩個要點 一是如何高效地上傳:使用MultipartFile替代FileOutputSteam 二是上傳文件的路徑問題的解決:使用路徑映射 文件路徑通常不在classpath,而是本地的一個固定路徑或者是一個文件伺服器路徑 SpringBoot的路徑: src/main/java:存放代碼 ...
文件上傳有兩個要點
一是如何高效地上傳:使用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等等