• Spring MVC 上传文件


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

  • 相关阅读:
    全文搜索引擎 Elasticsearch 入门教程
    什么是网络爬虫?
    如何更高效的使用谷歌解决问题
    python内置函数(2)-递归与迭代
    python内置函数(1)
    Life is short, you need Python
    统计单词个数及词频(C++实现)
    计算城市间的球面距离(C++实现)
    C++实现树的基本操作,界面友好,操作方便,运行流畅,运用模板
    C++,利用链式栈实现括号匹配,界面友好,操作方便,运行流畅
  • 原文地址:https://www.cnblogs.com/ooo0/p/11109316.html
Copyright © 2020-2023  润新知