7.2、使用基於 Servlet 3.0 的檔案上傳

行一發表於2016-11-06

  本文示例見這個專案的 upload 分支下的專案(這個專案是為本文單獨建立的)。

  WARNING:本文中有一部分直接把英文原文搬過來了,我的翻譯能力實在有限,湊合看吧。


  Spring 的內建 multipart 支援用於處理 Web 應用程式中的檔案上傳。你可以通過使用外掛化的MultipartResolver物件來啟用 multipart 支援,它定義在包org.springframework.web.multipart中。Spring 提供了一個MultipartResolver的實現,使用了 Apache 的 Commons FileUpload 和一些其他的東西,用於對 Servlet 3.0 的 multipart 請求的解析。

  預設地,Spring 不進行 multipart 處理,因為很多開發者想要自己處理。你可以通過在 Web 應用程式上下文中新增一個 multipart 解析器來啟用 Spring 的 multipart 處理。每一個請求都要被檢查,看看是否包含一個 multipart。如果沒有發現 multipart,請求就正常繼續啦;如果有的話,你在上下文中宣告的MultipartResolver就會開始工作啦。之後嘞,你就可以像訪問其他請求屬性那樣訪問 multipart 屬性啦。

和Servlet 3.0一起使用MultipartResolver

  為了使用基於 multipart 解析(parse)的 Servlet 3.0,你可以在DispatcherServlet上加個標記,這個標記可以是 web.xml 中的一個“multipart-config”片段,也可以是一個在程式設計 Servlet註冊中的 MultipartConfigElement(or with a javax.servlet.MultipartConfigElement in programmatic Servlet registration),or in case of a custom Servlet class possibly with a javax.servlet.annotation.MultipartConfig annotation on your Servlet class。配置設定如檔案最大長度或者儲存路徑需要應用在 Serlvet 註冊級別,因為 Servlet 3.0 不允許從MultipartResolver完成這些設定。

  一旦你通過上面的任意一種方式啟用了 Servlet 3.0 的 multipart解析,你需要新增StandardServletMultipartResolver`到你的 Spring 配置中:

<bean id="multipartResolver"
      class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>

配置 web.xml 檔案

  這裡使用<multipart-config/>。如下:

......
<servlet>
    <description>Spring MVC 核心 Servlet</description>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
    <multipart-config>
        <max-file-size>52428800</max-file-size>
        <max-request-size>52428800</max-request-size>
        <file-size-threshold>0</file-size-threshold>
    </multipart-config>
    <load-on-startup>1</load-on-startup>
</servlet>
......

在表單中處理檔案上傳

  在MultipartResolver完成自己的工作之後,你就可以像處理其他請求那樣處理當前請求了。首先,建立一個帶有<input type="file"/>的表單,這樣使用者就可以通過這個表單上傳檔案了。為表單新增編碼屬性 (enctype=”multipart/form-data”) 來讓瀏覽器直到把表單編碼為 multipart 請求:

<html>
    <head>
        <title>Upload a file please</title>
    </head>
    <body>
        <h1>Please upload a file</h1>
        <form method="post" action="/form" enctype="multipart/form-data">
            <input type="text" name="name"/>
            <input type="file" name="file"/>
            <input type="submit"/>
        </form>
    </body>
</html>

配置處理上傳檔案的控制器

  在使用 Servlet 3.0 的 multipart 解析時,你也可以使用javax.servlet.http.Part來作為方法引數:

@Controller
public class FileUploadController 
{
    @PostMapping("/form")
    public String handleFormUpload(
            @RequestParam("name") String name, 
            @RequestParam("file") Part file) 
    {
        InputStream inputStream = file.getInputStream();
        // store bytes from uploaded file somewhere
        return "redirect:uploadSuccess";
    }
}

相關文章