You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grails 4中如何捕获MaxUploadSizeExceededException文件上传异常?

问题分析

从异常栈可以看到,MaxUploadSizeExceededException是在HiddenHttpMethodFilter解析请求参数时触发的——此时请求还未到达控制器,也没进入Grails的URL映射处理流程,所以你之前在控制器中写的try-catch和URLMappings里的异常映射都无法捕获到这个异常。

解决方案

需要通过自定义过滤器提前拦截这个异常,且过滤器的执行顺序必须早于HiddenHttpMethodFilter。

步骤1:创建自定义异常处理过滤器

在项目中新建一个过滤器类,用于捕获上传大小超限的异常:

import org.springframework.web.multipart.MaxUploadSizeExceededException
import javax.servlet.*
import javax.servlet.http.HttpServletResponse
import java.io.IOException

class MultipartExceptionFilter implements Filter {

    @Override
    void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            chain.doFilter(request, response)
        } catch (MaxUploadSizeExceededException e) {
            handleUploadSizeException(response)
        }
    }

    private void handleUploadSizeException(ServletResponse response) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response
        httpResponse.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE)
        httpResponse.setContentType("text/html;charset=UTF-8")
        httpResponse.getWriter().write("文件大小超过限制,最大允许5MB")
    }

    @Override
    void destroy() {}
}

如果是前后端分离场景,可修改handleUploadSizeException方法返回JSON格式错误:

private void handleUploadSizeException(ServletResponse response) throws IOException {
    HttpServletResponse httpResponse = (HttpServletResponse) response
    httpResponse.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE)
    httpResponse.setContentType("application/json;charset=UTF-8")
    def errorInfo = [code: 413, message: "文件大小超过限制,最大允许5MB"]
    httpResponse.getWriter().write(new groovy.json.JsonBuilder(errorInfo).toString())
}

步骤2:注册过滤器并设置执行顺序

在grails-app/conf/spring/resources.groovy中注册过滤器,确保它的执行顺序早于HiddenHttpMethodFilter(HiddenHttpMethodFilter的默认顺序是Ordered.HIGHEST_PRECEDENCE + 10):

import your.package.MultipartExceptionFilter

beans = {
    multipartExceptionFilter(MultipartExceptionFilter) {
        order = org.springframework.core.Ordered.HIGHEST_PRECEDENCE + 5
    }
}

步骤3:配置Tomcat参数(可选但建议)

为了确保Tomcat不会提前截断请求导致异常无法被Spring捕获,在application.yml中添加Tomcat配置:

server:
  tomcat:
    max-swallow-size: -1  # 允许Tomcat处理超过大小限制的请求,让Spring捕获异常
原理说明

自定义过滤器的执行顺序优先于HiddenHttpMethodFilter,当请求后续流程中抛出MaxUploadSizeExceededException时,会被过滤器的try-catch捕获,从而可以返回自定义的错误提示,而不是让异常直接抛到控制台。

内容的提问来源于stack exchange,提问作者kofhearts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:24:57