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

Spring Boot REST API控制器异常处理方法及最佳实践咨询

Spring Boot REST API 异常处理优化指南

一、服务层异常抛出的优化

你当前的服务层代码存在两个可优化的点:

  1. 避免抛出通用Exception
    抛出宽泛的Exception会让异常处理逻辑模糊,无法精准区分业务错误类型。建议自定义业务异常,比如ItemNotFoundException,这样后续处理时能针对性返回响应。

  2. 冗余的Optional包装
    itemRepository.findById(itemId)本身返回Optional<Item>,调用orElseThrow()后,要么抛出异常,要么返回非空的Item实例,完全不需要再用Optional.ofNullable()包装,方法返回类型也可以直接改为Item(无需Optional<Item>)。

优化后的代码示例

首先定义自定义异常:

public class ItemNotFoundException extends RuntimeException {
    public ItemNotFoundException(String message) {
        super(message);
    }
}

修改服务层方法:

public Item getSpecificItem(Long itemId) {
    return itemRepository.findById(itemId)
            .orElseThrow(() -> new ItemNotFoundException("Item with id " + itemId + " doesn't exist"));
}

使用RuntimeException无需显式声明throws,Spring会自动捕获并交由异常处理器处理。

二、控制器异常处理方案对比

1. 控制器内单独处理(@ExceptionHandler)

这种方式适合单个控制器有特殊异常响应需求的场景,在控制器内部定义@ExceptionHandler方法处理指定异常:

@RestController
@RequestMapping("/items")
public class ItemController {
    @Autowired
    private ItemService itemService;

    @GetMapping("/{id}")
    public ResponseEntity<Item> getItem(@PathVariable Long id) {
        return ResponseEntity.ok(itemService.getSpecificItem(id));
    }

    @ExceptionHandler(ItemNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleItemNotFound(ItemNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }

    // 自定义错误响应DTO
    static class ErrorResponse {
        private int status;
        private String message;

        public ErrorResponse(int status, String message) {
            this.status = status;
            this.message = message;
        }

        // getter、setter 省略
    }
}

缺点:多个控制器存在相同异常处理逻辑时,会产生大量重复代码。

2. 全局异常处理(@RestControllerAdvice)

这是Spring Boot REST API异常处理的最佳实践,通过@RestControllerAdvice定义全局异常处理器,一次配置即可作用于所有控制器,避免代码重复,同时保证异常响应格式统一:

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理自定义业务异常
    @ExceptionHandler(ItemNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleItemNotFound(ItemNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }

    // 处理参数非法异常
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ErrorResponse> handleIllegalArgument(IllegalArgumentException ex) {
        ErrorResponse error = new ErrorResponse(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
    }

    // 兜底处理其他未捕获的异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
        ErrorResponse error = new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Internal server error");
        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    // 全局统一错误响应DTO
    static class ErrorResponse {
        private int status;
        private String message;

        public ErrorResponse(int status, String message) {
            this.status = status;
            this.message = message;
        }

        // getter、setter 省略
    }
}

优点:集中管理所有异常处理逻辑,响应格式统一,前端对接更顺畅,可维护性更高。

总结

  • 服务层优先抛出特定的自定义业务异常,替代通用Exception,提升代码可读性和异常处理的精准度。
  • 全局异常处理(@RestControllerAdvice)是REST API的推荐方案,除非单个控制器有特殊的异常响应需求,否则尽量使用全局处理器减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:01:01