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

Spring Boot全局异常处理器未捕获ResourceNotFoundException求助

解决Spring Boot中JAX-RS端点异常无法被@ControllerAdvice捕获的问题

你的问题根源很明确:你用了JAX-RS(Jersey)的注解来定义端点,但Spring的@ControllerAdvice只负责处理Spring MVC/Spring WebFlux控制器抛出的异常,对JAX-RS端点完全无效,所以抛出的ResourceNotFoundException才会直接返回堆栈跟踪,没有被全局处理器捕获。

下面给你两种可行的解决方案,根据你的技术选型来选:

方案一:继续使用JAX-RS,改用JAX-RS的异常处理机制

JAX-RS有自己的异常处理规范,需要实现ExceptionMapper接口并标注@Provider来全局捕获异常:

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class ResourceNotFoundExceptionMapper implements ExceptionMapper<ResourceNotFoundException> {
    @Override
    public Response toResponse(ResourceNotFoundException ex) {
        ExceptionResponse response = new ExceptionResponse();
        response.setErrorCode("resource not found");
        response.setErrorMessage(ex.getMessage());
        return Response.status(Response.Status.NOT_FOUND)
                .entity(response)
                .build();
    }
}

注意事项:

  • 确保这个@Provider类被Jersey的扫描机制覆盖到:如果你的Spring Boot项目用了spring-boot-starter-jersey,可以在Jersey的配置类里通过register(ResourceNotFoundExceptionMapper.class)手动注册,或者给这个类加上@Component让Spring自动管理(前提是Jersey和Spring整合正常)。

方案二:切换到Spring MVC注解,让@ControllerAdvice生效

如果没有必须用JAX-RS的理由,建议直接改用Spring MVC的注解,这样你的GlobalExceptionHandlerController就能正常工作了:

修改CustomerEndpoint的注解:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/customer")
public class CustomerEndpoint {
    private static final Logger LOGGER = LoggerFactory.getLogger(CustomerEndpoint.class);
    
    @Autowired
    private ICustomerService customerService;

    @GetMapping("/{id}")
    public ResponseEntity<CustomerVO> getCustomerById(@PathVariable("id") Integer id) throws ResourceNotFoundException {
        CustomerVO customer = customerService.getCustomerById(id);
        if (customer == null) {
            // 注意:构造器参数是long,要把Integer转成long
            throw new ResourceNotFoundException(id.longValue(), "Customer not found");
        }
        return ResponseEntity.ok(customer);
    }
}

额外检查点:

  1. 确认GlobalExceptionHandlerController所在的包被Spring的组件扫描覆盖到(比如和主启动类同包,或者通过@ComponentScan指定扫描路径)。
  2. 你原来的代码里抛出异常时写的customerId是未定义的变量,要改成方法参数id,并且转成long类型匹配构造器。

这样调整后,当请求不存在的客户ID时,ResourceNotFoundException就会被GlobalExceptionHandlerController捕获,返回你定义的ExceptionResponse格式的404响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:21