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

Spring Boot自定义ExceptionHandler未生效,请求排查原因

Spring Boot REST API 自定义异常未被捕获问题

我在Spring Boot开发REST API时,为了让客户端收到有意义的响应而非404,添加了异常处理逻辑,但抛出的自定义异常并未被处理器捕获。

相关代码

REST接口类

@Path("/v1")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Slf4j
@Service
@RequiredArgsConstructor
public class UserRestService {

    private final UserRepository userRepository;

    @GET
    @Path("/users/{publicId}")
    public RestResponse<UserListItemRestDto> getUserByPublicId(@PathParam("publicId") UUID publicId) {

        Optional<User> optionalUser = userRepository.findOneByPublicId(publicId);

        if(optionalUser.isEmpty()){
            throw new ApiRequestException("CANNOT FIND USER");
        }

        User user = optionalUser.get();

        return RestResponse.of(UserListItemRestDto.builder()
                        .email(user.getEmail())
                        .name(user.getName())
                .build());
    }

...

异常处理器类

@RestControllerAdvice
public class ApiExceptionHandler {

    @ExceptionHandler(ApiRequestException.class)
    public ResponseEntity<ApiException> handleApiRequestException(ApiRequestException e){
        return new ResponseEntity<>(new ApiException(e.getMessage(),
          e.getCause(),
          HttpStatus.BAD_REQUEST, 
          ZonedDateTime.now()),HttpStatus.BAD_REQUEST);
    }
}

自定义异常类

public class ApiRequestException extends RuntimeException{

    public ApiRequestException(String message){
        super(message);
    }

    public ApiRequestException(String message, Throwable cause){
        super(message,cause);
    }
}

报错信息

org.jboss.resteasy.spi.UnhandledException: com.common.rest.exception.ApiRequestException: CANNOT FIND USER
    at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:105) ~[resteasy-core-5.0.0.Final.jar:5.0.0.Final]
    ...(省略部分栈信息)
Caused by: com.common.rest.exception.ApiRequestException: CANNOT FIND USER
    at com.backend.flows.user.rest.UserRestService.getUserByPublicId(UserRestService.java:55) ~[classes/:na]
    ...(省略部分栈信息)

问题原因与解决方案

核心问题是技术栈不兼容:你用了JAX-RS(RESTEasy)的注解定义接口,但用了Spring MVC的@RestControllerAdvice做异常处理,两者不属于同一生态,无法互通。

方案一:切换为Spring MVC注解(推荐)

将JAX-RS注解替换为Spring MVC原生注解,保持Spring生态一致性:

@RequestMapping("/v1")
@RestController
@Slf4j
@RequiredArgsConstructor
public class UserRestService {

    private final UserRepository userRepository;

    @GetMapping("/users/{publicId}")
    public RestResponse<UserListItemRestDto> getUserByPublicId(@PathVariable UUID publicId) {

        Optional<User> optionalUser = userRepository.findOneByPublicId(publicId);

        if(optionalUser.isEmpty()){
            throw new ApiRequestException("CANNOT FIND USER");
        }

        User user = optionalUser.get();

        return RestResponse.of(UserListItemRestDto.builder()
                        .email(user.getEmail())
                        .name(user.getName())
                .build());
    }
}

修改后,原有的@RestControllerAdvice异常处理器就能正常捕获异常。

方案二:使用RESTEasy原生异常处理(若坚持用JAX-RS)

实现JAX-RS的ExceptionMapper接口来处理异常:

@Provider
public class ApiRequestExceptionMapper implements ExceptionMapper<ApiRequestException> {

    @Override
    public Response toResponse(ApiRequestException exception) {
        ApiException apiException = new ApiException(
                exception.getMessage(),
                exception.getCause(),
                HttpStatus.BAD_REQUEST,
                ZonedDateTime.now()
        );
        return Response.status(Response.Status.BAD_REQUEST)
                .entity(apiException)
                .type(MediaType.APPLICATION_JSON)
                .build();
    }
}

确保该类被Spring扫描到(放在主类的扫描包下,或通过@ComponentScan指定)。

额外注意:ApiException类需要提供完整的getter方法,否则序列化后客户端无法获取完整异常信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 04:35:36