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

如何在Spring Boot中用@ControllerAdvice处理404 NotFound异常?

解决Spring Boot中用@ControllerAdvice处理404(错误端点)异常的问题

首先明确:可以通过@ControllerAdvice处理请求错误端点的404异常,但你当前使用的javassist.NotFoundException完全不对,因为Spring MVC在找不到请求映射时,抛出的是特定的异常类,下面是具体解决方案:

1. 为什么当前代码不生效

当客户端请求不存在的端点时,Spring Boot默认不会抛出NotFoundException(不管是javassist还是自定义的),而是直接返回白标错误页面。只有配置开启后,Spring才会抛出org.springframework.web.servlet.NoHandlerFoundException,这才是你需要捕获的异常类。

2. 配置Spring Boot抛出NoHandlerFoundException

在application.properties中添加以下配置:

# 开启找不到处理器时抛出异常
spring.mvc.throw-exception-if-no-handler-found=true
# 关闭静态资源映射(避免静态资源路径干扰,比如/favicon.ico这类请求不会触发异常)
spring.web.resources.add-mappings=false

如果使用application.yml则配置如下:

spring:
  mvc:
    throw-exception-if-no-handler-found: true
  web:
    resources:
      add-mappings: false

3. 修改ControllerAdvice类

添加处理NoHandlerFoundException的方法,同时移除无用的javassist.NotFoundException相关代码:

import com.ds.ecommerce.exception.PriceNotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.xml.bind.ValidationException;

@Slf4j
@ControllerAdvice
public class PricesGlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorDTO handleException(Exception exception) {
        log.error(exception.getMessage(), exception);
        return ErrorDTO.builder()
                .code(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase())
                .message("Unexpected error!")
                .build();
    }

    @ResponseBody
    @ExceptionHandler(value = {ValidationException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorDTO handleException(ValidationException validationException) {
        String exceptionMessage = validationException.getMessage();
        log.error(exceptionMessage, validationException);
        return ErrorDTO.builder()
                .code(HttpStatus.BAD_REQUEST.getReasonPhrase())
                .message(exceptionMessage)
                .build();
    }

    @ResponseBody
    @ExceptionHandler(value = {PriceNotFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorDTO handleException(PriceNotFoundException priceNotFoundException) {
        String exceptionMessage = priceNotFoundException.getMessage();
        log.error(exceptionMessage, priceNotFoundException);
        return ErrorDTO.builder()
                .code(HttpStatus.NOT_FOUND.getReasonPhrase())
                .message(exceptionMessage)
                .build();
    }

    // 新增:处理请求不存在端点的404异常
    @ResponseBody
    @ExceptionHandler(value = {NoHandlerFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorDTO handleNoHandlerFoundException(NoHandlerFoundException ex) {
        String message = String.format("请求的路径 %s 不存在", ex.getRequestURL());
        log.error(message, ex);
        return ErrorDTO.builder()
                .code(HttpStatus.NOT_FOUND.getReasonPhrase())
                .message(message)
                .build();
    }
}

4. 补充说明

  • PriceNotFoundException是你自定义的业务异常,用于处理业务逻辑中找不到资源(比如找不到商品价格)的场景,和请求错误端点的404属于不同场景。
  • 配置spring.web.resources.add-mappings=false是为了确保静态资源的请求(比如/css、/js)也会触发NoHandlerFoundException,如果你的项目需要保留静态资源映射,可以根据实际情况调整,但此时静态资源路径的请求不会进入异常处理器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:06:18