[英]Spring Boot Returning 401 Statused Custom Object From Exception Handler
我有一個 Spring Boot rest API,它有一個 LoginController 用於執行簡單的身份驗證過程。 這是令牌驗證操作。
@PostMapping("validatetoken")
public ResponseEntity<ValidateTokenResponse> validateToken(
@RequestBody ValidateTokenRequest validateTokenRequest, HttpServletRequest request) throws Exception {
if (StringUtils.isEmpty(validateTokenRequest.getToken())) throw new AuthenticationFailedException("token parameter cannot be null or empty");
Boolean isValid = authenticationService.validateToken(request, validateTokenRequest.getToken());
ValidateTokenResponse response = new ValidateTokenResponse();
response.setIsValid(isValid);
response.setToken(validateTokenRequest.getToken());
return new ResponseEntity<>(response, isValid? HttpStatus.OK : HttpStatus.UNAUTHORIZED);
}
在我的 api 中,我在ResponseEntityExceptionHandler
捕獲所有錯誤並以這種方式轉換自定義對象。
@ExceptionHandler(AuthenticationFailedException.class)
@ResponseBody
protected ResponseEntity<Object> handleAuthenticationFailed(AuthenticationFailedException ex) {
LogManager.error(ex);
ApiError apiError = new ApiError(HttpStatus.UNAUTHORIZED);
apiError.setMessage(ex.getMessage());
return buildResponseEntity(apiError);
}
但是,當我想使用如下所示的RestTemplate
調用此 api 時,我收到了類似java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode 的異常。
ResponseEntity<String> responseEntity =
restTemplate.exchange(
this.validateTokenUrl,
HttpMethod.POST,
requestHttpEntity,
String.class);
但是如果我將HttpStatus
從ExceptionHandler
更改為 except HttpStatus.UNAUTHORIZED
我可以從客戶端獲取真正的ApiError
對象。 什么可能導致此問題,我該如何解決?
編輯:創建了一個github repo來模仿我項目中的問題部分。
默認情況下, RestTemplate
使用DefaultResponseErrorHandler
。 每當從REST API發送4xx / 5xx響應時,此錯誤處理程序就會引發異常。
如果要自定義錯誤處理,只需通過restTemplate.setErrorHandler
注冊您的自定義錯誤處理程序,即可在其中使用ResponseErrorHandler
接口的實現。
為了清楚起見,我建議將帶有以下詳細信息的resttemplate自動連接到單獨的配置文件中
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new ErrorHandler());
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setOutputStreaming(false);
restTemplate.setRequestFactory(requestFactory);
return restTemplate;
}
這是 SimpleClientHttpRequestFactory 的默認行為(使用 JDK 的內部 http 客戶端)
一個簡單的解決方法是使用 apache http 組件庫:
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
restTemplate.setRequestFactory(requestFactory);
有關更多詳細信息,請參閱此鏈接: https : //github.com/spring-projects/spring-security-oauth/issues/441#issuecomment-92033542
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.