1. 程式人生 > 實用技巧 >SpringMVC-11-檔案上傳和下載

SpringMVC-11-檔案上傳和下載

11. 檔案上傳和下載

準備工作

​ springMVC可以很好的支援檔案上傳,但是SpringMVC上下文預設沒有裝配MultipartResolver,因此預設情況下不能處理檔案上傳工作。如果想實現,必須在上下文配置MultipartResolver

​ 前端表單要求:為了能上傳檔案,必須使用POST,並將enctype設定為multipart/form-data。瀏覽器可以把使用者選擇的檔案以二進位制資料傳送給伺服器。

對錶單的enctype屬性的詳細說明

  • application/x-www=form-urlencoded:預設方式,只處理value值,表單域中的值會處理成URL編碼。
  • multipart/form-data:二進位制流的方式處理表單資料。封裝到請求引數中,不會對字元編碼。
  • text/plain:除了把空格轉換成+號,其他字元不做編碼處理,這種方式適合直接通過表單傳送郵件。

Apache釋出開源的Commons FileUpload元件:

  • Servlet 3.0規範已經提供方法來處理檔案上傳;
  • SpringMVC提供了更簡單的封裝;
  • 即插即用的MultipartResolver實現了這個功能;
  • SpringMVC使用Apache Commons FileUpload技術實現了一個MultipartResolver實現類。

檔案上傳

  1. 匯入檔案上傳的jar包,commons-fileupload,Maven會自動幫我們匯入她的依賴包 commons-io包:

    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
    </dependency>
    
  2. 配置bean:multipartResolver

    【注意!這個bean的id必須是multipartResolver,否則檔案會報404】

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--請求的編碼格式 必須和jsp的pageEncoding一致-->
        <property name="defaultEncoding" value="utf-8"/>
        <!--上傳檔案的大小上限 10M-->
        <property name="maxUploadSize" value="10485760"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>
    

CommonsMultipartFile的常用方法:

  • String getOriginalFilename():獲取上傳檔案的原名;
  • InputStream getInputStream():獲取檔案流
  • void transferTo(File dest):將上傳檔案儲存到一個目錄檔案
  1. 編寫前端頁面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>$Title$</title>
    </head>
    <body>
    <form action="${pageContext.request.contextPath}/upload2" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="upload">
    </form>
    </body>
    </html>
    
  2. Controller

    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
    
        String uploadFilename = file.getOriginalFilename();
    
        if("".equals(uploadFilename)){
            return "redirect:/index.jsp";
        }
        System.out.println("上傳檔名:"+uploadFilename);
    
        String path = request.getServletContext().getRealPath("/upload");
    
        File realPath = new File(path);
        if (!realPath.exists())
            realPath.mkdir();
        System.out.println("檔案儲存地址:"+realPath);
    
        InputStream is = file.getInputStream();
        FileOutputStream os = new FileOutputStream(new File(realPath, uploadFilename));
    
        int len=0;
        byte[] buffer = new byte[1024];
        while((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }
    

採用file.Transto來儲存上傳的檔案

  1. 編寫Controller

    @RequestMapping("/upload2")
    public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
        String path = request.getServletContext().getRealPath("/upload");
    
        File realPath = new File(path);
        if (!realPath.exists())
            realPath.mkdir();
        System.out.println("上傳檔案儲存地址:"+realPath);
    
        file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));
        return "redirect:/index.jsp";
    }
    
  2. 前端表單提交地址修改

  3. 訪問提交測試

檔案下載

步驟:

  1. 設定response請求頭
  2. 讀取檔案--InputStream
  3. 寫出檔案--OutputStream
  4. 執行操作
  5. 關閉流
@RequestMapping("/download")
public String downloads(HttpServletResponse response,HttpServletRequest request) throws IOException {
    String path = request.getServletContext().getRealPath("/upload");
    String fileName="基礎語法.jpg";

    response.reset();
    response.setCharacterEncoding("UTF-8");
    response.setContentType("multipart/form-data");

    response.setHeader("Content-Disposition",
            "attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));
    File file = new File(path, fileName);
    InputStream inputStream = new FileInputStream(file);
    OutputStream outputStream = response.getOutputStream();

    byte[] buffer = new byte[1024];
    int index=0;
    while((index=inputStream.read(buffer))!=-1){
        outputStream.write(buffer,0,index);
        outputStream.flush();
    }
    outputStream.close();
    inputStream.close();
    return null;
}