繁体   English   中英

Spring Boot默认异常映射到标准HTTP状态代码

[英]Spring Boot default exceptions mapped to standard HTTP status codes

我知道可以在Spring Boot中定义自定义异常处理程序,并将例如IllegalArgumentException异常映射到HTTP 400错误请求。 我想知道在Spring Web / Boot中定义的任何现有异常都映射到标准HTTP状态代码吗? 这样我就可以抛出它们,它们将被自动映射到标准HTTP状态代码。

实际上,默认情况下,ResponseEntityExceptionHandler会将Spring内部抛出的异常转换为HTTP状态代码。 但是,将异常转换为HTTP状态代码不会提供有关该异常的任何重要日志。 良好的安全实践要求,从外部分发的错误消息应尽可能少地提供有关系统内部的信息。 相反,日志应尽可能多地提供信息。

此外,ResponseEntityExceptionHandler仅处理Spring生成的异常。 所有与业务相关的异常都必须单独处理。 例如,此类未处理从findSomething(xxx)方法引发的“未找到记录”异常。

以下是解决这些缺点的示例:

Spring抛出的内部错误您必须重写所关注异常的处理程序,并提供内部日志消息和外部错误消息,以将它们返回给调用方。

@ControllerAdvice是一个注释,它包装了@Component类和声明了@ExceptionHandler注释方法的类。 简而言之,这些处理程序将包装所有@Component方法。

@Slf4j
@ControllerAdvice
public class InternalExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    public ResponseEntity<Object> handleMissingServletRequestParameter(
            MissingServletRequestParameterException e,
            HttpHeaders headers,
            HttpStatus status,
            WebRequest request) {

        LogError error = new LogError("MissingServletRequestParameterException", 
                HttpStatus.BAD_REQUEST,
                String.format("Missing '%s' parameter", e.getParameterName()));
        log.debug(error.toJson());

        HttpErrorResponse response = new HttpErrorResponse(error.getStatus(), e.getMessage());
        return new ResponseEntity<>(response.toJson(),
                HeaderFactory.getErrorHeaders(),
                response.getStatus());
    }

    ....
}

业务层抛出错误

您必须首先为每个异常创建一个特定的RuntimeException类,并为它加上@ResponseStatus注释。

@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Record not found") //
public class RecordNotFoundException extends RuntimeException {

    private static final long serialVersionUID = 8857378116992711720L;

    public RecordNotFoundException() {
        super();
    }

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

然后,创建一个带@ControllerAdvice注释的类,该类将保存所有这些异常处理程序方法。 没有类可以派生,因为这些@ExceptionHandler注释方法的内部重定向由Spring管理。

@Slf4j
@ControllerAdvice
public class ClientExceptionHandler {

    @ExceptionHandler(value = RecordNotFoundException.class)
    public ResponseEntity<String> handleRecordNotFoundException(
            RecordNotFoundException e,
            WebRequest request) {

        LogError logging = new LogError("RecordNotFoundException",
                HttpStatus.NOT_FOUND, 
                request.getDescription(true));
        log.info(logging.toJson());

        HttpErrorResponse response = new HttpErrorResponse(logging.getStatus(), e.getMessage());
        return new ResponseEntity<>(response.toJson(),
                HeaderFactory.getErrorHeaders(),
                response.getStatus());
    }
   ....
}

最后,帮助程序类LogError和HttpErrorResponse是它们各自目标的简单格式化程序。

希望这可以帮助。

可靠的人

有少数映射到405的HttpRequestMethodNotSupportedException ,例如HttpRequestMethodNotSupportedException

看一下ResponseEntityExceptionHandler.handleException()方法,该方法定义了用于处理Spring MVC中常见异常的基本规则。 你会找到

NoSuchRequestHandlingMethodException.class,
HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class,
HttpMediaTypeNotAcceptableException.class,
MissingPathVariableException.class,
MissingServletRequestParameterException.class,
ServletRequestBindingException.class,
ConversionNotSupportedException.class,
TypeMismatchException.class,
HttpMessageNotReadableException.class,
HttpMessageNotWritableException.class,
MethodArgumentNotValidException.class,
MissingServletRequestPartException.class,
BindException.class,
NoHandlerFoundException.class,
AsyncRequestTimeoutException.class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM