繁体   English   中英

如何更改 Spring Boot 错误响应中的状态代码?

[英]How to change Status code in spring boot error response?

我正在制作一个简单的休息服务,它使用 RestTemplate 进行一些 http 调用和聚合数据。

有时我会收到 NotFound 错误,有时会收到 BadRequest 错误。

我想用相同的状态代码响应我的客户端,而 Spring 似乎具有开箱即用的映射。 消息没问题,但状态代码始终为 500 内部服务器错误。

我想将我的状态代码映射到我最初收到的状态代码

    "timestamp": "2019-07-01T17:56:04.539+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "400 Bad Request",
    "path": "/8b8a38a9-a290-4560-84f6-3d4466e8d7901"
}

我希望它是这样的

    "timestamp": "2019-07-01T17:56:04.539+0000",
    "status": 400,
    "error": "Internal Server Error",
    "message": "400 Bad Request",
    "path": "/8b8a38a9-a290-4560-84f6-3d4466e8d7901"
}

它抛出 HttpClientErrorException.BadRequest 或 HttpClientErrorException.NotFound

我的代码是一个简单的端点:

    @GetMapping("/{id}")
    public MyModel getInfo(@PathVariable String id){
        return MyService.getInfo(id);
    }

您可以使用@ControllerAdvice注释创建全局异常处理。 像这样:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = YourExceptionTypes.class)
    protected ResponseEntity<Object> handleBusinessException(RuntimeException exception, WebRequest request) {
        return handleExceptionInternal(exception, exception.getMessage(), new HttpHeaders(), HttpStatus.NOT_ACCEPTABLE, request);
    }
}

当抛出异常时,处理程序将捕获并将其转换为所需的响应。 原始异常不会被传播。

接受的@ControllerAdvice解决方案是不够的。 这肯定会使用异常的自定义状态代码标记响应。 但是,它不会将想要的响应主体作为 JSON 返回,而是作为简单的字符串返回 - 来自异常的消息。

要获得正确的状态代码和默认错误正文, DefaultErrorAttributes可以提供帮助。

@ControllerAdvice
public class PackedTemplateNotRecodableExceptionControllerAdvice extends ResponseEntityExceptionHandler {
    @Autowired
    private DefaultErrorAttributes defaultErrorAttributes;

    @ExceptionHandler(PackedTemplateNotRecodableException.class)
    public ResponseEntity<Object> handlePackedTemplateNotRecodableException(final RuntimeException exception, final WebRequest webRequest) {
        // build the default error response
        webRequest.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, HttpStatus.BAD_REQUEST.value(), RequestAttributes.SCOPE_REQUEST);
        final Map<String, Object> errorAttributes = defaultErrorAttributes.getErrorAttributes(webRequest, ErrorAttributeOptions.defaults());

        // return the error response with the specific response code
        return handleExceptionInternal(exception, errorAttributes, new HttpHeaders(), HttpStatus.BAD_REQUEST, webRequest);
    }
}

这样你会收到想要的错误响应,例如这样的:

{
    "timestamp": "2019-07-01T17:56:04.539+0000",
    "status": 400,
    "error": "Internal Server Error",
    "message": "400 Bad Request",
    "path": "/8b8a38a9-a290-4560-84f6-3d4466e8d7901"
}

我花了很多时间研究这个问题,包括这里答案的解决方案,这对我不起作用(或者我没有正确实施)。

我终于有了突破。 我没有抛出诸如throw new Exception(message)类的通用异常,而是创建了扩展特定异常类型的Exception类的类 - 以及它们各自的 HTTP 错误代码和消息

@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class BadRequestException extends Exception{

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

在您的应用程序逻辑中,您现在可以使用类似throw new BadRequestException("Invalid Email")的消息抛出 Bad Request 异常。 这将导致抛出异常,因此:

{
"timestamp": "2021-03-01T17:56:04.539+0000",
"status": 400,
"error": "Bad Request",
"message": "Invalid Email",
"path": "path to controller"
}

您现在可以按照上述示例并更改 @ResponseStatus 中的 value 参数,为所需的不同异常创建其他自定义异常类,以匹配所需的响应代码。 例如,对于 NOT FOUND 异常@ResponseStatus (value = HttpStatus.NOT_FOUND) ,Java 通过HttpStatus枚举提供不同的 HTTP 状态代码。

更多上下文

我希望这足够详细并且可以帮助某人:)

Spring Resttemplate 异常处理的可能重复您的代码需要一个控制器通知来处理来自它正在调用的服务的异常。

暂无
暂无

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

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