【问题标题】:Java create custom exception class with specific status codeJava创建具有特定状态码的自定义异常类
【发布时间】:2019-07-17 20:38:29
【问题描述】:

在 Spring Boot 中,我创建了具有特定状态代码的自定义异常类,我调用它来抛出异常,代码为:100 和消息:控制器处的消息:“没有内容”,但输出仍然返回“状态”:500 和“ error": "内部服务器错误"

AppException.java

public class AppException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private final Integer code;

    public AppException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }
}

UserController.java

@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping()
    public ApiResponseDto getAllUsers(Pageable pageable) {
        Page<User> users = userService.getAllUsers(pageable);

        if (users.getSize() < 0) {
            throw new AppException(100, "No have content");
        }

        return new ApiResponseDto(HttpStatus.OK.value(), users);
    }

实际输出:

{
    "timestamp": 1550987372934,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "com.app.core.exception.AppException",
    "message": "No have content",
    "path": "/api/user"
}

我的期望:

{
    "timestamp": 1550987372934,
    "status": 100,
    "error": "No have content",
    "exception": "com.app.core.exception.AppException",
    "message": "No have content",
    "path": "/api/user"
}

【问题讨论】:

    标签: java spring-boot exception


    【解决方案1】:

    如果您想为您的 API 进行全局异常处理,并希望有自定义错误响应,您可以添加 @ControllerAdvice

    @ControllerAdvice
    public class ApiExceptionHandler {
    
        @ExceptionHandler({ ApiException.class })
        protected ResponseEntity<ApiErrorResponse> handleApiException(ApiException ex) {
            return new ResponseEntity<>(new ApiErrorResponse(ex.getStatus(), ex.getMessage(), Instant.now()), ex.getStatus());
        }
    }
    
    // you can put any information you want in ApiErrorResponse 
    public class ApiErrorResponse {
    
        private final HttpStatus status;
        private final String message;
        private final Instant timestamp;
    
        public ApiError(HttpStatus status, String message, Instant timestamp) {
            this.status= status;
            this.message = message;
            this.timestamp = timestamp;
        }
    
        public HttpStatus getStatus() { 
            return this.status; 
        }
    
        public String getMessage() {
            return this.message;
        }
    
        public Instant getTimestamp() {
            return this.timestamp;
        }
    }
    
    // your custom ApiException class
    public class ApiException extends RuntimeException {
    
        private final HttpStatus status;
    
        public ApiException(HttpStatus status, String message) {
            super(message);
            this.status = status;
        }
    
        public HttpStatus getStatus() {
            return this.status;
        }
    }
    

    【讨论】:

    • 谢谢,但是抛出 new AppException(100, "No have content");是例子。因为,我想在项目中的许多状态代码中使用 AppException 类
    • @Tony 我更新了答案,以防您希望对 API 进行全局异常处理,并且更喜欢自定义错误响应。
    • 谢谢,但我想在任何服务类、java 类等处抛出异常,而不是返回控制器。顺便说一句,使用 @ControllerAdvice 它也不会准确返回我为 ApiException(整数代码,字符串消息)放置的状态代码。你能建议我其他方式吗?
    • @Tony 异常可能会在您的代码中的任何位置引发。在ApiException 中也使用HttpStatus 而不是Integer
    【解决方案2】:

    有多种方法可以实现这一点:

    1. 异常处理程序

      您可以在控制器中添加 @ExceptionHandler 注释方法:

      @ExceptionHandler({ CustomException1.class, CustomException2.class })
      public void handleException() {
      //
      }
      
    2. HandlerExceptionResolver

      您还可以实现自定义解析器来拦截所有异常并通过覆盖doResolveException 方法来全局处理它们

    关于以上两种方法的更多细节可以在这里找到:https://www.baeldung.com/exception-handling-for-rest-with-spring

    【讨论】:

      【解决方案3】:

      如果您需要有限数量的不同错误消息,或者您想多次重复使用相同的错误消息,那么您只需要这样:

      @ResponseStatus(value = HttpStatus.CONTINUE, reason = "No have content")
      public class AppException extends RuntimeException {
          private static final long serialVersionUID = 1L;
      }
      

      不需要任何额外的类和处理程序。您的代码将清晰明了。

      你可以像这样简单地提高它:

      throw new AppException();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-21
        • 1970-01-01
        • 2021-12-29
        • 2023-03-07
        • 2019-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多