簡體   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