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>

  完成上述步骤操作后,限制文件上传类型就完成了,读者也可以自行测试。

时间: 2024-12-22 18:05:34

Spring MVC环境中文件上传大小和文件类型限制以及超大文件上传bug问题的相关文章

Spring MVC程序中得到静态资源文件css,js,图片文件的路径问题总结

上一篇 | 下一篇 Spring MVC程序中得到静态资源文件css,js,图片 文件的路径 用 Spring MVC 开发应用程序,对于初学者有一个很头疼的问题,那就是程序数据都已经查询出来了,但界面样式仍然十分丑陋,加载不了 css,js,图片等资源文件.当你在浏览器上直接输入某个css文件的路径时,直接得到404错误,而路径肯定没有错,其原因就在于在web.xml 中配置了类似如下的 spring servlet: 程序代码 <servlet>    <servlet-name&g

Spring MVC 环境搭建(maven+SpringMVC+mybatis+Freemarker) ----DawnHeaven

Spring MVC 环境搭建(maven+SpringMVC+mybatis+Freemarker)       ------DawnHeaven 一.准备工作 1.Eclipse Java EE IDE(4.4.1) 2.JDK 3.Tomcat 4.Maven  maven安装指南 二.构建工程 1.file->new->Project 2.next 3. next 4.next 5.finish 工程目录如下 三.完善项目 首先,完善目录,增加重要的source Folder,这个不是

spring MVC环境搭建

1.新建web项目,并在web.xml加入spring mvc的servlet <!-- spring mvc容器和servlet的定义 --> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 这里的参数如果不

Spring MVC 环境搭建(一)

一.建立 JavaWeb 项目 1.建立一个 Java 项目. 2.在项目下新建一个文件夹 webapp (命名可自取,这个目录即是网站根目录),再在该文件夹下新建一个 WEB-INF 文件夹(命名固定),WEB-INF 作为 Tomcat 启动后的安全文件夹,浏览器不能访问到该目录下的资源.tomcat 启动会默认会在此目录下读取相应配置文件. 3.在 WEB-INF 下建立 web.xml 文件(命名固定),从 tomcat 安装路径 /conf/web.xml 中拷贝基本的文档结构,修改相

Spring MVC Controller中解析GET方式的中文参数会乱码的问题

Spring MVC Controller中解析GET方式的中文参数会乱码的问题 问题描述 在工作上使用Spring老是碰到一个问题,使用Controller处理GET方式的请求参数时,服务端得到的结果会碰到乱码,之前翻阅了很多与Java EE相关的很多乱码处理资料,不管是加过滤器还是统一文件编码,都没能正确解决,后来设计接口时,一直采用先Base64,然后再作为参数传过来的方式解决的.最近找到了根本的解决方案,顺手记下来. 为何会乱码 Spring MVC 是基于Servlet,在Http请求

Spring MVC 环境搭建

作为java领域不可或缺的一员猛将,今天我开始正式接触它.与所有框架一样,我们第一步要做的就是搭建环境. 首先我们需要准备的材料: Eclipse tomcat(我用的是7.0) spring mvc jar包(我用的是3.2的) 有了这些工具,下面我们开始吧! 1.新建一个项目 Eclipse新建 Dynamic Web project 选择相应的服务器容器(我用的是Tomcat7.0),一路下一步到完成. 2.引入jar包 SpringMVC使用的jar包基本和Spring是相同的,我们可以

Spring MVC环境搭建与基本操作

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还可以是 Struts 这样的 Web 框架. [转载使用,请注明出处:http://blog.csdn.net/mahoking] 本例使用的Spring版本为Spring-3.2.0.M1. 点击下载! 操作步骤: 1. 

Spring MVC Controller中解析GET方式的中文参数会乱码的问题(tomcat如何解码)

Spring MVC Controller中解析GET方式的中文参数会乱码的问题 问题描述 在工作上使用突然出现从get获取中文参数乱码(新装机器,tomcat重新下载和配置),查了半天终于找到解决办法. 为何会乱码 Spring MVC 是基于Servlet,在Http请求到达Servlet解析之前,GET过来的URL已经被Tomcat先做了一次URLDecode.Tomcat对GET方式默认的URL解码结果是iso-8859-1而不是我认为的UTF-8. 解决方案 解决方案也很简单,除了平常

如何在Spring MVC工程中进行单元测试

直接以代码方式演示如何在Spring MVC工程中进行单元测试: package net.chinaedu.projects.dubhe; import java.util.List; import net.chinaedu.projects.dubhe.publisher.IPublisherService; import net.chinaedu.projects.venus.domain.Publisher; import org.junit.Test; import org.junit.