Java创建具有特定状态代码的自定义异常类

时间:2019-02-24 06:20:13

标签: java spring-boot exception

在Spring Boot中,我创建具有特定状态代码的自定义异常类,并调用该异常类以引发代码为100的异常并在控制器上显示消息:“ No have content”,但输出仍返回“ status”:500和“错误”:“内部服务器错误”

AppException.java

<html>

<head>
  <meta charset="utf-8">
  <title> THis is the title </title>
  <style>
    .clicker {
      border-style: solid;
      border-width: 1px;
      display: inline-block;
      padding: 5px;
      outline: none;
      cursor: pointer;
    }
    
    .hiddendiv {
      display: none;
      padding: 5px;
    }
    
    .clicker:focus+.hiddendiv {
      display: block;
      border: 1px solid blue;
    }
    
    .clicker:focus {
      background: green;
      border: 1px solid blue;
    }
  </style>
</head>

<body>

  <h2> Flashcards</h2>
  <div class="clicker" tabindex="1">
    <p>This is the first question </p>
  </div>
  <div class="hiddendiv">
    <img src="https://cdn4.iconfinder.com/data/icons/champions-1/512/Champions-04-512.png" />
  </div>
  <p> </p>
  <div class="clicker" tabindex="1">
    <p>Second question </p>
  </div>
  <div class="hiddendiv">
    <img src="https://cdn4.iconfinder.com/data/icons/champions-1/512/Champions-04-512.png" />
  </div>
  <p> </p>
</body>

</html>

UserController.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;
    }
}

实际输出:

@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"
}

3 个答案:

答案 0 :(得分:2)

如果您希望对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;
    }
}

答案 1 :(得分:0)

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

  1. ExceptionHandler

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

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

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

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

答案 2 :(得分:0)

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

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

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

您可以像这样简单地提出它:

throw new AppException();