Spring MVC 上傳文件

  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

MultipartResolver概述

<!-- 配置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

相關文章
相關標籤/搜索