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

MethodArgumentNotValidException未在过滤器捕获及返回404问题排查

问题根源分析

1. 过滤器未捕获MethodArgumentNotValidException的原因

Spring请求处理流程中,过滤器(Filter)执行在DispatcherServlet之前。控制器层抛出的MethodArgumentNotValidException会被DispatcherServlet触发的全局异常处理器(@ControllerAdvice)捕获处理,不会向上传播到过滤器的catch块。过滤器的try-catch仅能捕获filter chain执行阶段(如请求预处理)抛出的异常,无法覆盖控制器层及后续环节的异常。

2. 全局异常处理后返回404的原因

全局异常处理器的handleValidationException方法返回JSON字符串,但Spring MVC会将该返回值视为视图名称,尝试转发到对应路径的资源。从日志可见,系统试图转发到以完整JSON字符串为路径的资源:

Forwarding to [{"statusCode":400,"status":"Bad Request",...}]

该路径不存在对应资源,因此触发NoResourceFoundException,最终返回404状态码。

解决方法

修复全局异常处理器

将异常处理方法改为直接返回错误对象,并通过@RestControllerAdvice或@ResponseBody让Spring直接序列化对象为JSON响应,而非当作视图名称处理:

方案一:使用@RestControllerAdvice替代@ControllerAdvice

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<GenericErrorRes> handleValidationException(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getFieldErrors().stream()
                .map(error -> error.getField() + ": " + error.getDefaultMessage()).findFirst().orElse("");
        GenericErrorRes errorRes = new GenericErrorRes();
        errorRes.setStatusCode(HttpStatus.BAD_REQUEST.value());
        errorRes.setStatus(HttpStatus.BAD_REQUEST.getReasonPhrase());
        errorRes.setErrorDesc(message);
        errorRes.setErrorCode(MNDT_PARAM_ERROR);
        errorRes.setMoreDetails(MNDT_PARAM_ERROR_MESSAGE);
        
        return new ResponseEntity<>(errorRes, HttpStatus.BAD_REQUEST);
    }
}

方案二:保留@ControllerAdvice并添加@ResponseBody

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public GenericErrorRes handleValidationException(MethodArgumentNotValidException ex) {
        // 同上构建errorRes的逻辑
        return errorRes;
    }
}

过滤器异常捕获补充说明

若需在过滤器层面处理控制器异常,无法通过直接捕获chain.doFilter的异常实现。可通过自定义DispatcherServlet或扩展HandlerExceptionResolver实现,但这类方案复杂度较高,不如直接完善全局异常处理器的实现更简洁。

另外,当前过滤器的try-catch块仅打印日志,未做后续响应处理,即使捕获到异常也无法生成正确响应,建议根据需求补充异常处理逻辑(如直接向response写入错误信息)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:14:52