繁体   English   中英

Spring 中的自定义 Http 状态代码

[英]Custom Http Status Code in Spring

我正在使用 Spring Boot 并且在我的业务逻辑代码中使用异常类。 一个可能看起来像这样:

@ResponseStatus(HttpStatus.BAD_REQUEST)
public class ExternalDependencyException extends RuntimeException {

    public ExternalDependencyException() {
        super("External Dependency Failed");
    }
    public ExternalDependencyException(String message) {
        super(message);
    }

}

那么现在有异常,没有预定义的 Http 状态代码适合,所以我想使用像 460 或类似的状态代码,它仍然是免费的,但注释ResponseStatus只接受来自枚举HttpStatus值。 有没有办法在java spring boot环境中实现带有自定义状态码的Exception类?

我不知道有什么方法可以用@ResponseStatus做到这一点

解决此问题的一种方法是使用@RestControllerAdvice 这将允许您自定义返回异常的方式。

@RestControllerAdvice
public class WebRestControllerAdvice  {

    @ExceptionHandler(ExternalDependencyException.class)
    public String handleGitlabException(ExternalDependencyException ex, HttpServletResponse response) {
        try {
            response.sendError(460);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ex.getMessage();
    }
}

一般来说,@mdeterman 的回答很好,但我相信正确的做法是 setStatus 来响应,而不是直接发送错误。 示例:

@RestControllerAdvice
public class CustomExceptionHandler { 
    @ExceptionHandler(CustomException.class)
    public String handleException(Exception ex, HttpServletResponse response) {
        response.setStatus(460);
        return ex.getMessage();
    }
}

似乎只有因为@RestControllerAdvice 才有可能。 @ControllerAdvice 在视图解析器级别重置状态代码(出于某种奇怪的原因)。 同样重要的是要了解:如果客户端服务基于 spring 任何自定义状态代码(在 org.apache.http.HttpStatus - RFC1945、RFC2616 和 RFC2518 中未提及)都将导致 UnknownHttpStatusCodeException。

是的, sendError()将使用 Spring 默认模板。 您还需要使用RestControllerAdvice而不是ControllerAdvice ,然后setStatus()就可以了:)

@RestControllerAdvice
public class ExceptionService {

    @SneakyThrows
    @ExceptionHandler({CustomException.class})
    public CustomExceptionDto handle(HttpServletResponse resp, CustomException e) {
        resp.setStatus(e.getStatus().value()); //Using Spring HttpStatus
        return e.toDto();
    }

}

在 Spring Boot 2.1.8.RELEASE 中,我做了类似的事情,但没有使用 HttpServletResponse:

@RestControllerAdvice
public class RestExceptionHandler {

    @ExceptionHandler(MyCustomException.class)
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public ApiErrorResponse handleTemplateEngineException(MyCustomException ex) {

        //custom ApiErrorResponse class
        return ApiErrorResponse.builder()
                .status(HttpStatus.NOT_ACCEPTABLE)
                .errorCode("NOT_ACCEPTABLE")
                .message(ex.getLocalizedMessage()).build();
    }
}

暂无
暂无

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

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