J'appelle un service ReST
via RestTemplate
et j'essaie de remplacer ResponseErrorHandler
dans Spring 3.2
pour gérer les codes d'erreur personnalisés.
CustomResponseErrroHandler
public class MyResponseErrorHandler implements ResponseErrorHandler {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
boolean hasError = false;
int rawStatusCode = response.getRawStatusCode();
if (rawStatusCode != 200){
hasError = true;
}
return hasError;
}
@Override
public void handleError(ClientHttpResponse response) throws IOException {
//String body = IOUtils.toString(response.getBody());
throw new CustomServiceException(response.getRawStatusCode() , "custom Error");
}
}
Spring
framework invoque la méthode hasError
mais pas handleError
, donc je ne pouvais pas lever mon exception personnalisée. Après avoir exploré le code source de Spring
RestTemplate
, je me suis rendu compte que le code de la méthode handleResponseError
est à l'origine du problème - Il recherche response.getStatusCode
ou response.getStatusText
et lançant une exception (comme statusCode/statusText est nul lorsque Rest
le service lève une exception) et il n'appelle jamais la méthode implémentée personnalisée ou la méthode par défaut handleError
dans la ligne suivante.
Spring
RestTemplate
code source de la méthode handleResponse
:
private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException {
if (logger.isWarnEnabled()) {
try {
logger.warn(method.name() + " request for \"" + url + "\" resulted in " +
response.getStatusCode() + " (" + response.getStatusText() + "); invoking error handler");
}
catch (IOException e) {
// ignore
}
}
getErrorHandler().handleError(response);
}
Pour info, alors que le service lève une exception, je peux lire le rawstatuscode mais pas le statuscode de la réponse
Comment contourner ce code framework et faire appeler mon gestionnaire personnalisé? Merci d'avance pour votre aide.
Le lien suivant contient des informations utiles sur Flux d'exceptions pour Spring ResponseErrorHandler .
Ajout de code ici, juste au cas où le blog serait en panne:
Code pour ErrorHandler:
public class MyResponseErrorHandler implements ResponseErrorHandler {
private static final Log logger = LogFactory.getLog(MyResponseErrorHandler.class);
@Override
public void handleError(ClientHttpResponse clienthttpresponse) throws IOException {
if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
logger.debug(HttpStatus.FORBIDDEN + " response. Throwing authentication exception");
throw new AuthenticationException();
}
}
@Override
public boolean hasError(ClientHttpResponse clienthttpresponse) throws IOException {
if (clienthttpresponse.getStatusCode() != HttpStatus.OK) {
logger.debug("Status code: " + clienthttpresponse.getStatusCode());
logger.debug("Response" + clienthttpresponse.getStatusText());
logger.debug(clienthttpresponse.getBody());
if (clienthttpresponse.getStatusCode() == HttpStatus.FORBIDDEN) {
logger.debug("Call returned a error 403 forbidden resposne ");
return true;
}
}
return false;
}
}
Code pour l'utiliser dans RestTemplate:
RestTemplate restclient = new RestTemplate();
restclient.setErrorHandler(new MyResponseErrorHandler());
ResponseEntity<String> responseEntity = clientRestTemplate.exchange(
URI,
HttpMethod.GET,
requestEntity,
String.class);
response = responseEntity.getBody();
Je ne vois pas votre code RestTemplate
, mais je suppose que vous définissez votre ResponseErrorHandler
pour RestTemplate
à utiliser comme:
RestTemplate restClient = new RestTemplate();
restClient.setErrorHandler(new MyResponseErrorHandler());
L'exception est en effet levée dans la méthode handleError
. Vous pouvez trouver comment lancer CustomException
en utilisant CustomResponseHandler
à partir de ne de mes réponses précédentes .