Spring MVC 上传文件

半腔热情 提交于 2020-01-29 15:41:19

  Spring MVC的文件上传是通过MultipartResolver(Multipart解析器)处理的,对于MultipartResolver而言它只是一个接口,它有两个实现类。
  •CommonsMultipartResolver:依赖于Apache下的jakartaCommon FileUpload项目解析Multipart请求,可以在Spring的各个版本中使用,只是它要依赖于第三方包才得以实现。
  •StandardServletMultipartResolver:是Spring 3.1版本后的产物,它依赖于Servlet 3.0或者更高版本的实现,它不用依赖第三方包。

  对于两者而言,笔者更倾向于StandardServletMultipartResolver,因为它无须引入任何第三方包,只是当项目使用Spring3.1以下的版本或者Servlet 3.0以下的版本时,只能选择CommonsMultipartResolver。本书会以StandardServletMultipartResolver为主,CommonsMultipartResolver为辅介绍文件上传方面的内容。无论在你的项目中使用的是CommonsMultipartResolver还是StandardServletMultipartResolver,都要配置一个MultipartResolver。

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请求对象。

提交上传文件表单

  代码清单15-53:定义文件上传表单

<%@ 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会解析失败。

代码清单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的思维,高度的解耦性。此外,它也简化了许多关于文件的操作,这样对文件上传的开发就更为便利了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!