【Java Web開發學習】Spring MVC文件上傳html
轉載:https://www.cnblogs.com/yangchongxing/p/9290489.htmljava
文件上傳有兩種實現方式,都比較簡單web
方式1、使用StandardServletMultipartResolverspring
依賴Servlet3.0對Multipart請求的支持,須要MultipartConfigElement配置請求的相關參數json
Java配置方式數組
@Bean public MultipartResolver multipartResolver() { return new StandardServletMultipartResolver(); }
在Servlet中指定multipart配置,經過MultipartConfigElement設置上傳臨時路徑,上傳文件大小,上傳請求的大小。xcode
經過重載protected void customizeRegistration(ServletRegistration.Dynamic registration)方法實現,看代碼mvc
package cn.ycx.web.config; import java.io.IOException; import java.util.Properties; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletRegistration; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // 將一個或多個路徑映射到DispatcherServlet上 @Override protected String[] getServletMappings() { return new String[] {"/"}; } // 返回的帶有@Configuration註解的類將會用來配置ContextLoaderListener建立的應用上下文中的bean @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] {RootConfig.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] {ServletConfig.class}; } @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { // 上傳文件的臨時目錄 String location = "/tmp"; // 上傳文件的最大容量 long maxFileSize = 3145728; // 請求的最大容量 long maxRequestSize = 3145728; // 上傳的最小臨界值,大於該值纔會被寫入文件保存 // int fileSizeThreshold = 0; try { Properties prop = new Properties(); prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("upload.properties")); location = prop.getProperty("temporary.location"); maxFileSize = Long.parseLong(prop.getProperty("max.file.size")); maxRequestSize = Long.parseLong(prop.getProperty("max.request.size")); } catch (IOException e) {} // 文件上傳配置 registration.setMultipartConfig(new MultipartConfigElement(location, maxFileSize, maxRequestSize, 0)); // 沒有找處處理的請求拋出異常 boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); if(!done) throw new RuntimeException("設置異常(throwExceptionIfNoHandlerFound)"); } }
xml-base方式app
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"></bean>
web.xml配置DispatcherServlet初始化參數ide
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> ...省略... <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>0</load-on-startup> <multipart-config> <!--臨時文件的目錄--> <location>E:/tmp</location> <!-- 上傳文件最大3M --> <max-file-size>3145728</max-file-size> <!-- 上傳文件整個請求不超過3M --> <max-request-size>3145728</max-request-size> </multipart-config> </servlet> ...省略... </web-app>
Html代碼
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="/mvc/upload" enctype="multipart/form-data" method="post"> <input name="fileData" type="file"> <input type="submit" value="上傳"> </form> </body> </html>
一、控制器接受文件原始byte[]。這種方式不可取,雖然能保存文件,可是咱們不知道文件原始名稱,也不知道文件類型。
@RequestMapping("/upload") public Map<String, String> upload(@RequestPart("fileData") byte[] fileData) throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHssmm"); if (fileData != null) { FileOutputStream out = new FileOutputStream(new File("F:\\war\\" + format.format(new Date()))); out.write(fileData); out.close(); } Map<String, String> data = new HashMap<String, String>(); data.put("status", "ok"); return data; }
二、控制器接受MultipartFile類型
Multipart接口
public interface MultipartFile extends InputStreamSource { String getName();//參數名字 String getOriginalFilename();//原始文件名 String getContentType();//類型 boolean isEmpty();//文件是否空 long getSize();//文件字節大小 byte[] getBytes() throws IOException;//返回字節數組 @Override InputStream getInputStream() throws IOException;//輸入流 void transferTo(File dest) throws IOException, IllegalStateException;//轉換文件 }
控制器代碼
@RequestMapping("/upload") public Map<String, String> upload(MultipartFile fileData) throws Exception { if (fileData != null) { SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHssmm"); fileData.transferTo(new File("F:\\war\\" + format.format(new Date()) + "_" + fileData.getOriginalFilename()));//保存文件 } Map<String, String> data = new HashMap<String, String>(); data.put("status", "ok"); return data; }
三、控制器接受Part類型
Part接口
public interface Part { public InputStream getInputStream() throws IOException;//輸入流 public String getContentType();//類型 public String getName();//參數名 public String getSubmittedFileName();//原始文件名 public long getSize();//字節大小 public void write(String fileName) throws IOException;//保存文件 public void delete() throws IOException;//刪除文件 public String getHeader(String name);//獲取頭信息 public Collection<String> getHeaders(String name);//獲取頭信息 public Collection<String> getHeaderNames();//獲取頭信息 }
控制器代碼
@RequestMapping("/upload") public Map<String, String> upload(@RequestPart("fileData") Part fileData) throws Exception { if (fileData != null) { SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHssmm"); fileData.write("F:\\war\\" + format.format(new Date()) + "_" + fileData.getSubmittedFileName());//保存文件 } Map<String, String> data = new HashMap<String, String>(); data.put("status", "ok"); return data; }
方式2、使用CommonsMultipartResolver
依賴 commons-fileupload.jar 和 commons-io.jar。上傳臨時路徑,文件大小都在對象中設置。
code-base方式
@Bean public MultipartResolver multipartResolver() throws IOException { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setUploadTempDir(new FileSystemResource(config.uploadTemporaryLocation())); multipartResolver.setMaxUploadSize(config.uploadMaxFileSize()); multipartResolver.setMaxInMemorySize(0); return multipartResolver; }
xml-base方式
<!-- 上傳文件 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"/> <!-- 最大內存大小 --> <property name="maxInMemorySize" value="10240"/> <!-- 最大文件大小,-1爲不限制大小 --> <property name="maxUploadSize" value="-1"/> </bean>
示例代碼:
實現了核心部分僅供參考。
package cn.ycx.web.controller; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import cn.ycx.web.config.PropertyConfig; /** * 上傳 * @author 楊崇興 2018-07-09 */ @Controller @RequestMapping("/upload") public class UploadController extends BaseController { /** * 屬性配置 */ @Autowired private PropertyConfig config; @RequestMapping(value="/image", method=RequestMethod.POST, produces="application/json;charset=UTF-8") public String image(@RequestParam(value = "imageFile", required = false) MultipartFile multipartFile) { try { String serverPath = config.uploadImageSavePath() + new SimpleDateFormat("yyyy/MM/dd/").format(new Date()); File serverPathFile = new File(serverPath); //目錄不存在則建立 if (!serverPathFile.exists()) { serverPathFile.mkdirs(); } String fileName = multipartFile.getOriginalFilename(); multipartFile.transferTo(new File(serverPath + fileName)); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return "success"; } }
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>上傳</title> </head> <body> <form action="/ycxcode/upload/image" method="post" enctype="multipart/form-data"> <input type="text" name="discription" value="discription"/> <input type="file" name="imageFile"> <input type="submit" value="submit"/> </form> </body> </html>