Spring MVC文件上传大小和类型限制以及超大文件上传bug问题

在上一篇文章中,主要介绍了Spirng MVC环境下的正常情况下文件上传功能实现。在实际开发的时候,还会涉及到上传文件大小和类型的限制,接下来就会对Spirng MVC环境下文件上传大小和类型的限制进行介绍,还会讲解到文件上传大小tomcat服务器bug问题及解决方案。

一、文件上传大小限制

这里还是接着上篇文章先介绍Spring MVC下的文件上传大小限制,文件上传大小的限制在springmvc-config.xml中配置文件解析器CommonsMultipartResolver时即可配置,示例如下:

<!-- 配置文件上传类型解析器 multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!-- 设置上传文件最大尺寸,单位为B -->
  <property name="maxUploadSize" value="5242880" />
</bean>

关于Spring MVC中文件上传大小的限制就这么简单,问题是Spring MVC并没有像Struts2那样的配置,如果单纯配置一个限制文件上传大小的配置,当超过上传限制后就会出现异常:

所以当在文件解析器中配置了文件大小的限制后,必须将抛出的MaxUploadSizeExceededException(上传文件过大异常)进行接收并跳转。关于异常接收,在Spring MVC官方文档中介绍了有3种方法,这里主要介绍其中2种:

(1)直接在配置文件spring-config.xml中使用Spring MVC提供的SimpleMappingExceptionResolver(异常解析映射器)来接收异常信息:

<!-- 1.在文件上传解析时发现异常,此时还没有进入到Controller方法中 -->
<bean id="exceptionResolver" class= "org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="exceptionMappings">
    <props>
    <!-- 遇到MaxUploadSizeExceededException异常时,跳转到error.jsp页面 -->
    <prop key= "org.springframework.web.multipart.MaxUploadSizeExceededException">/error </prop>
    </props>
  </property>
</bean>

这样当再出现文件上传大小的异常时,配置文件会自动捕获异常并进行匹配,匹配到对应的MaxUploadSizeExceededException异常,就跳转到指定的error.jsp错误页面。

(2)另一种就是自定义一个异常处理器类,可以匹配接收各种异常,同时可以指定跳转页面以及错误提示信息:

/**
 * 自定义异常处理器类
 */
public class ExceptionHandler implements HandlerExceptionResolver{
  /**
   * 处理上传文件大小超过限制抛出的异常
   */
  @Override
  public ModelAndView resolveException(HttpServletRequest req,
      HttpServletResponse res, Object ob,Exception ex) {
    ModelAndView mv=new ModelAndView();
    //判断异常类型,来跳转不同页面
    if (ex instanceof MaxUploadSizeExceededException){
      //指定错误信息
      mv.addObject("errormessage", "上传文件过大");
      //设置跳转视图
      mv.setViewName("userEdit");
      return mv;
    }
    //其他异常
    return null;
  }
}

上面自定的异常处理器类,模拟接收了抛出的MaxUploadSizeExceededException异常,完成自定义异常处理器类后,还必须进行在spring-config.xml配置文件中配置:

<!-- 2.配置自定义异常处理器类 -->
<bean class="com.itheima.exception.ExceptionHandler" />

上面就介绍完了2种主要的Spring MVC中文件上传大小限制及异常捕获的方案,读者可以自行测试。

补充:文件上传大小限制tomcat服务器bug问题

在使用上述2种文件上传大小限制及异常捕获配置后,当上传文件大小超过限制一定范围后,可以正确捕获异常并且跳转到指定页面,但是当上传文件超大(严重超出上传大小限制)时,就可能出现关于MaxUploadSizeExceededException 死循环状态,此时页面直接崩溃。

关于这个异常问题,在市面书籍、课程资料中都没有提及这一点,都有意避之(因为开发中可能更多的使用插件进行文件上传和下载,而不是用框架自带的,另外这个bug问题目前也未能有效解决)。针对这个问题,查询了官方文档以及相关资料都没有明确的解决方案和问题说明。不过在一篇老外的bug报告中提及到这个bug问题,可以参考链接:https://bz.apache.org/bugzilla/show_bug.cgi?id=57438;在文章中说明了这可能是tomcat服务器的bug问题,而非Spring MVC框架问题,如果使用tomcat7.0.39版本的话,这个问题就不存在了。

所以针对Spring MVC文件上传大小限制出现的这个问题,可以换用tomcat7.0.39版本的tomcat服务器;或者使用另一种思路。

目前可行的解决方案:

首先在配置文件解析器时,不使用Spring MVC提供的文件上传大小限制属性<property name="maxUploadSize" value="5242880" />,示例如下:

<!-- 配置文件上传类型解析器 multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

然后自定义一个拦截器来限定文件上传大小,并模拟抛出MaxUploadSizeExceededException异常:

public class FileUploadInterceptor extends HandlerInterceptorAdapter {
  private long maxSize;

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //判断是否文件上传
    if(request!=null && ServletFileUpload.isMultipartContent(request)) {
      ServletRequestContext ctx = new ServletRequestContext(request);
      //获取上传文件尺寸大小
      long requestSize = ctx.contentLength();
      if (requestSize > maxSize) {
        //当上传文件大小超过指定大小限制后,模拟抛出MaxUploadSizeExceededException异常
        throw new MaxUploadSizeExceededException(maxSize);
      }
    }
    return true;
  }
  public void setMaxSize(long maxSize) {
    this.maxSize = maxSize;
  }
}

最后在spring-config.xml中配置拦截上传大小限制的拦截器:

<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/**"/>
    <bean class="com.itheima.interceptor.FileUploadInterceptor">
      <!-- 设定限制的文件上传大小 -->
      <property name="maxSize" value="5242880"/>
    </bean>
  </mvc:interceptor>
</mvc:interceptors>

这样就可以完成在Spring MVC环境下文件上传大小的限制以及异常正确捕获了。

二、文件上传类型的限制

在这里讲解之前必须要声明的是,在Spring MVC配置下,并没有像Struts2配置文件中那样配置一个拦截器就可以同时限定上传文件大小和类型。同时在官方文档以及其相关资料中也没有提出在Spring MVC环境中限制文件上传类型的解决方案,不过这里我们仍然可以使用自定义拦截器来限制文件上传类型。

首先自定义一个文件上传类型限制的拦截器,示例如下:

/**
 * 全局文件类型拦截器
 */
public class FileTypeInterceptor extends HandlerInterceptorAdapter {
  @Override
  public boolean preHandle(HttpServletRequest request,
      HttpServletResponse response, Object handler)throws Exception {
    boolean flag= true;
    // 判断是否为文件上传请求
    if (request instanceof MultipartHttpServletRequest) {
      MultipartHttpServletRequest multipartRequest =
          (MultipartHttpServletRequest) request;
      Map<String, MultipartFile> files =
                    multipartRequest.getFileMap();
      Iterator<String> iterator = files.keySet().iterator();
      //对多部件请求资源进行遍历
      while (iterator.hasNext()) {
        String formKey = (String) iterator.next();
        MultipartFile multipartFile =
               multipartRequest.getFile(formKey);
        String filename=multipartFile.getOriginalFilename();
        //判断是否为限制文件类型
        if (! checkFile(filename)) {
          //限制文件类型,请求转发到原始请求页面,并携带错误提示信息
          request.setAttribute("errormessage", "不支持的文件类型!");
          request.getRequestDispatcher("/WEB-INF/jsp/userEdit.jsp")
          .forward(request, response);
          flag= false;
        }
      }
    }
    return flag;
  }
  /**
   * 判断是否为允许的上传文件类型,true表示允许
   */
  private boolean checkFile(String fileName) {
    //设置允许上传文件类型
    String suffixList = "jpg,gif,png,ico,bmp,jpeg";
    // 获取文件后缀
    String suffix = fileName.substring(fileName.lastIndexOf(".")
        + 1, fileName.length());
    if (suffixList.contains(suffix.trim().toLowerCase())) {
      return true;
    }
    return false;
  }
}

在上述示例中,自定义的拦截器限制了文件上传类型为:String suffixList = "jpg,gif,png,ico,bmp,jpeg";当拦截成功后会重回远请求页面,并携带错误信息。

然后在spring-config.xml中配置自定义拦截器,示例如下:

<mvc:interceptors>
  <!-- 如果有多个拦截器,则按照顺序进行配置 -->
  <mvc:interceptor>
    <!-- /**表示所有URL和子URL路径 -->
    <mvc:mapping path="/**" />
    <!-- 配置自定义的文件上传类型限制拦截器 -->
    <bean class="com.itheima.interceptor.FileTypeInterceptor" />
  </mvc:interceptor>
</mvc:interceptors>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • MyBatis与SpringMVC相结合实现文件上传、下载功能

    环境:maven+SpringMVC + Spring + MyBatis + MySql 本文主要说明如何使用input上传文件到服务器指定目录,或保存到数据库中:如何从数据库下载文件,和显示图像文件并实现缩放. 将文件存储在数据库中,一般是存文件的byte数组,对应的数据库数据类型为blob. 首先要创建数据库,此处使用MySql数据库. 注意:文中给出的代码多为节选重要片段,并不齐全. 1. 前期准备 使用maven创建一个springMVC+spring+mybatis+mysql的项目

  • SpringMvc MultipartFile实现图片文件上传示例

    整理文档,搜刮出一个SpringMvc MultipartFile实现图片文件上传示例,稍微整理精简一下做下分享. spring-servlet.xml <!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver&qu

  • SpringMVC文件上传 多文件上传实例

    必须明确告诉DispatcherServlet如何处理MultipartRequest.SpringMVC中提供了文件上传使用方式如下配置xxx-servlet.xml,添加如下代码: 复制代码 代码如下: <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">          <!-- 设置

  • springMVC实现前台带进度条文件上传的示例代码

    项目框架采用spring+hibernate+springMVC如果上传文件不想使用flash那么你可以采用HTML5;截图前段模块是bootstarp框架;不废话直接来代码;spring-mvc配置文件;效果截图如下: 详细实现如下: 1.mvc-config.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/s

  • springMVC配置环境实现文件上传和下载

    最近的项目中用到了文件的上传和下载功能,我觉着这个功能比较重要,因此特意把它提取出来自己进行了尝试. 下面就是springMVC配置环境实现文件上传和下载的具体步骤,供大家参考,具体内容如下 一. 基础配置: maven导包及配置pom.xml,导包时除开springmvc的基础依赖外,需要导入文件上传下载时用到的commons-io.jsr和commons-fileupload.jar: <project xmlns="http://maven.apache.org/POM/4.0.0&

  • SpringMVC文件上传的配置实例详解

    记述一下步骤以备查. 准备工作: 需要把Jakarta Commons FileUpload及Jakarta Commons io的包放lib里. 我这边的包是: commons-fileupload-1.1.1.jar commons-io-1.3.2.jar 然后在spring-servlet.xml进行multipartResolver配置,不配置好上传会不好用. <bean id="multipartResolver" class="org.springfram

  • Spring MVC中上传文件实例

    SpringMVC(注解)上传文件需要注意的几个地方: 1.form的enctype="multipart/form-data",这个是上传文件必须的 2.applicationContext.xml配置: 复制代码 代码如下: <!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 --> <bean id="multipartResolver" class="org.springframework.w

  • 使用jQuery.form.js/springmvc框架实现文件上传功能

    使用的技术有jquery.form.js框架, 以及springmvc框架.主要实现异步文件上传的同时封装对象,以及一些注意事项. 功能本身是很简单的,但是涉及到一些传递参数类型的问题.例如:jquery的ajax方法与jquery.form.js中的ajaxSubmit方法的参数,具体细节将在下一篇博客中分享. 重点: html表格三要素: action="fileUpload/fileUpload" method="post" enctype="mul

  • Spring MVC文件上传大小和类型限制以及超大文件上传bug问题

    在上一篇文章中,主要介绍了Spirng MVC环境下的正常情况下文件上传功能实现.在实际开发的时候,还会涉及到上传文件大小和类型的限制,接下来就会对Spirng MVC环境下文件上传大小和类型的限制进行介绍,还会讲解到文件上传大小tomcat服务器bug问题及解决方案. 一.文件上传大小限制 这里还是接着上篇文章先介绍Spring MVC下的文件上传大小限制,文件上传大小的限制在springmvc-config.xml中配置文件解析器CommonsMultipartResolver时即可配置,示

  • 详解Spring MVC自动为对象注入枚举类型

    如果一个对象里面有枚举类型的话,则spring MVC是不能够直接进行注入的,因为它只实现了一些基本的数据类型的自动转换注入,但是其也提供了可扩展的接口,可以根据自己的需要来进行扩展.下面是一个示例: 首先:这是一个枚举类: /** * 新闻类别 * @author: ShangJianguo * 2014-6-11 上午10:51:07 */ public enum ENews { company("0"), // 企业新闻 industry("1");// 行业

  • Spring MVC处理参数中的枚举类型通用实现方法

    前言 在开发的过程中,会涉及到大量的枚举类型数据,我们都知道,Springmvc本身能自动转换很多的数据类型,也支持你自定义转换类型,非常灵活. 本文主要介绍的是关于Spring MVC处理参数的枚举类型通用实现的相关内容,下面话不多说了,来一起看看详细的介绍吧 业务场景: 前端提交了枚举的一个属性value,想由spring来完成参数类型自动转换成对应的枚举. 比方有一个枚举 @AllArgsConstructor(access = AccessLevel.PRIVATE) @Getter @

  • SpringBoot如何通过配置文件(yml,properties)限制文件上传大小

    目录 通过配置文件(yml,properties)限制文件上传大小 properties类型配置文件设置 yml类型配置文件设置 设置文件上传大小限制--默认为1M 解决方法 通过配置文件(yml,properties)限制文件上传大小 properties类型配置文件设置 # springboot 1.X spring.http.multipart.max-file-size=50Mb   spring.http.multipart.max-request-size=50Mb   # spri

  • spring mvc+localResizeIMG实现HTML5端图片压缩上传

    最近在做一个移动端HTML5的应用,使用到了上传功能,起初使用传统的上传方式上传手机拍照的照片,由于手机拍照出来的照片一般都是好几MB,所以上传速度是非常慢的. 在网上找了很久找到了localResizeIMG压缩框架,感觉非常的实用,所以在此分享给大家. 第一步:下载localResizeIMG localResizeIMG放在github中的,地址是:https://github.com/think2011/localResizeIMG. 第二步:在web工程中导入localResizeIM

  • Maven工程搭建spring boot+spring mvc+JPA的示例

    本文介绍了Maven工程搭建spring boot+spring mvc+JPA的示例,分享给大家,具体如下: 添加Spring boot支持,引入相关包: 1.maven工程,少不了pom.xml,spring boot的引入可参考官网: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId>

  • spring mvc路径匹配原则详解

    在Spring MVC中经常要用到拦截器,在配置需要要拦截的路径时经常用到<mvc:mapping/>子标签,其有一个path属性,它就是用来指定需要拦截的路径的.例如: <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.i360r.platform.webapp.runtime.view.interceptor.GenericInterceptor"

  • Spring MVC学习之DispatcherServlet请求处理详析

    前言 要深入理解spring mvc的工作流程,就需要先了解spring mvc的架构: 从上图可以看到 前端控制器DispatcherServlet在其中起着主导作用,理解了DispatcherServlet 就完全可以说弄清楚了spring mvc. DispatcherServlet作为Spring用于处理web请求注册的唯一一个Servlet,所有的请求都是经由DispatcherServlet进行分发处理的.本文主要讲解DispatcherServlet是如何对请求进行分发,处理,并且

  • Spring MVC的国际化实现代码

    Spring MVC的国际化是建立在Java国际化的基础上的,其一样是通过提供不同国家的语言环境的消息资源.通过ResourceBundle加载Locale对应的资源文件.再取得该资源文件中指定Key对应的消息. 步骤: 1.给系统加载国际化资源 2.输出国际化.Spring MVC输出国际化消息有两种方式. 在页面上输出国际化消息.需要使用Spring MVC的标签库. 在Controller的处理方法中输出国际化消息.需要使用org.springframework.web.servlet.s

  • Eclipse使用maven搭建spring mvc图文教程

    本文为大家介绍了Eclipse使用maven搭建spring mvc的详细步骤,供大家参考,具体内容如下 1. 环境配置 a). Java 1.7 b). Eclipse luna c). Maven3.2.5 d). Spring 4.1.4 2. 创建maven工程 a). 打开eclipse,file->new->project->Maven->Maven Project b). 下一步 c). 选择创建的工程为webapp,下一步 d). 填写项目的group id和art

随机推荐