Spring MVC的文件上傳是經過MultipartResolver(Multipart解析器)處理的,對於MultipartResolver而言它只是一個接口,它有兩個實現類。
•CommonsMultipartResolver:依賴於Apache下的jakartaCommon FileUpload項目解析Multipart請求,能夠在Spring的各個版本中使用,只是它要依賴於第三方包才得以實現。
•StandardServletMultipartResolver:是Spring 3.1版本後的產物,它依賴於Servlet 3.0或者更高版本的實現,它不用依賴第三方包。html
對於二者而言,筆者更傾向於StandardServletMultipartResolver,由於它無須引入任何第三方包,只是當項目使用Spring3.1如下的版本或者Servlet 3.0如下的版本時,只能選擇CommonsMultipartResolver。本書會以StandardServletMultipartResolver爲主,CommonsMultipartResolver爲輔介紹文件上傳方面的內容。不管在你的項目中使用的是CommonsMultipartResolver仍是StandardServletMultipartResolver,都要配置一個MultipartResolver。java
<!-- 配置DispatcherServlet --> <servlet> <!-- 注意:Spring MVC 框架會根據 servlet-name 配置,找到/WEB-INF/dispatcher-servlet.xml做爲配置文件載入Web工程中 --> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 使得Dispatcher在服務器啓動的時候就初始化 --> <load-on-startup>2</load-on-startup> <!--MultipartResolver參數--> <multipart-config> <location>d:/uploads/</location> <max-file-size>5242880</max-file-size> <max-request-size>10485760</max-request-size> <file-size-threshold>0</file-size-threshold> </multipart-config> </servlet>
在Spring MVC中,對於MultipartResolver解析的調度是經過DispatcherServlect進行的。它首先斷定請求是不是一種enctype="multipart/*"請求,若是是而且存在一個名稱爲multi-partResolver的Bean定義,那麼它將會把HttpServletRequest請求轉換爲MultipartHttp ServletRequest請求對象。web
代碼清單15-53:定義文件上傳表單spring
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>文件上傳</title></head> <body> <form method="post" action="../file/uploadMultipartFile.do" enctype="multipart/form-data"> <input type="file" name="file" value="請選擇上傳的文件"/> <input type="submit" value="提交"/> </form> </body> </html>
要把enctype定義爲"multipart/form-data",不然Spring MVC會解析失敗。json
代碼清單15-54:控制器處理文件上傳請求服務器
package com.ssm.chapter15.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Part; import java.io.File; import java.io.IOException; @Controller @RequestMapping("/file") public class FileController { @RequestMapping("/upload") public ModelAndView upload(HttpServletRequest request) { //進行轉換 MultipartHttpServletRequest mhsr = (MultipartHttpServletRequest) request; // 得到請求上傳的文件 MultipartFile file = mhsr.getFile("file"); // 設置視圖爲JSON視圖 ModelAndView mv = new ModelAndView(); mv.setView(new MappingJackson2JsonView()); // 獲取原始文件名 String fileName = file.getOriginalFilename(); // 目標文件 File dest = new File(fileName); try { //保存文件 file.transferTo(dest); // 保存成功 mv.addObject("success", true); mv.addObject("msg", "上傳文件成功"); } catch (IllegalStateException | IOException e) { // 保存失敗 mv.addObject("success", false); mv.addObject("msg", "上傳文件失敗"); e.printStackTrace(); } return mv; } // 使用MultipartFile @RequestMapping("/uploadMultipartFile") public ModelAndView uploadMultipartFile(MultipartFile file) { // 定義JSON視圖 ModelAndView mv = new ModelAndView(); mv.setView(new MappingJackson2JsonView()); // 獲取原始文件名 String fileName = file.getOriginalFilename(); file.getContentType(); // 目標文件 File dest = new File(fileName); try { // 保存文件 file.transferTo(dest); mv.addObject("success", true); mv.addObject("msg", "上傳文件成功"); } catch (IllegalStateException | IOException e) { mv.addObject("success", false); mv.addObject("msg", "上傳文件失敗"); e.printStackTrace(); } return mv; } // 使用Part @RequestMapping("/uploadPart") public ModelAndView uploadPart(Part file) { ModelAndView mv = new ModelAndView(); mv.setView(new MappingJackson2JsonView()); // 獲取原始文件名 String fileName = file.getName(); File dest = new File(fileName); try { // 保存文件 file.write("d:/uploads/" + fileName); mv.addObject("success", true); mv.addObject("msg", "上傳文件成功"); } catch (IllegalStateException | IOException e) { mv.addObject("success", false); mv.addObject("msg", "上傳文件失敗"); e.printStackTrace(); } return mv; } }
上面使用了MultipartFile和Part,它們的好處是把代碼從Servlet API中解放出來,這體現了Spring的思惟,高度的解耦性。此外,它也簡化了許多關於文件的操做,這樣對文件上傳的開發就更爲便利了。app