web-dev-qa-db-fra.com

Comment extraire le code d'état HTTP de l'appel RestTemplate vers une URL?

J'utilise RestTemplate pour passer un appel HTTP à notre service qui renvoie une réponse JSON simple. Je n'ai pas du tout besoin d'analyser ce JSON. Je dois juste retourner ce que je reçois de ce service.

Je mappe donc cela à String.class et renvoie le JSON response réel sous forme de chaîne.

RestTemplate restTemplate = new RestTemplate();

String response = restTemplate.getForObject(url, String.class);

return response;

Maintenant la question est - 

J'essaie d'extraire HTTP Status codes après avoir cliqué sur l'URL. Comment puis-je extraire le code d'état HTTP à partir du code ci-dessus? Dois-je apporter des changements à cela dans la façon dont je le fais actuellement?

Mettre à jour:-

C’est ce que j’ai essayé et je peux également obtenir la réponse et le code de statut. Mais est-ce que je dois toujours définir les objets HttpHeaders et Entity comme ci-dessous que je le fais?

    RestTemplate restTemplate = new RestTemplate();     

    //and do I need this JSON media type for my use case?
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);

    //set my entity
    HttpEntity<Object> entity = new HttpEntity<Object>(headers);

    ResponseEntity<String> out = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);

    System.out.println(out.getBody());
    System.out.println(out.getStatusCode());

Quelques questions - Dois-je avoir MediaType.APPLICATION_JSON car je viens d'appeler un url qui renvoie une réponse, il peut renvoyer JSON ou XML ou une simple chaîne.

28
john

Utilisez les méthodes RestTemplate#exchange(..) qui renvoient un ResponseEntity . Cela vous donne accès à la ligne d'état et aux en-têtes (et au corps évidemment).

26

Si vous ne voulez pas laisser l'abstraction de Nice autour des méthodes RestTemplate.get/postForObject... comme moi et que vous n'aimez pas tripoter les éléments indispensables lorsque vous utilisez RestTemplate.exchange... (Request- and ResponseEntity, HttpHeaders, etc.), vous disposez d'une autre option les codes HttpStatus.

Entourez simplement le RestTemplate.get/postForObject... habituel d'un try/catch pour org.springframework.web.client.HttpClientErrorException et org.springframework.web.client.HttpServerErrorException, comme dans cet exemple:

try {
    return restTemplate.postForObject("http://your.url.here", "YourRequestObjectForPostBodyHere", YourResponse.class);

} catch (HttpClientErrorException | HttpServerErrorException httpClientOrServerExc) {

    if(HttpStatus.NOT_FOUND.equals(httpClientOrServerExc.getStatusCode())) {
      // your handling of "NOT FOUND" here  
      // e.g. throw new RuntimeException("Your Error Message here", httpClientOrServerExc);
    }
    else {
      // your handling of other errors here
}

Le org.springframework.web.client.HttpServerErrorException est ajouté ici pour les erreurs avec un 50x.

Vous pouvez maintenant réagir simplement à tous les StatusCodes de votre choix - sauf celui qui convient, qui correspond à votre méthode HTTP - comme GET et 200, qui ne seront pas gérés comme des exceptions, car il s'agit de la méthode correspondante. Mais cela devrait être simple, si vous implémentez/utilisez des services RESTful :) 

6
jonashackt
private RestTemplate restTemplate = new RestTemplate();

ResponseEntity<String> response = restTemplate.exchange(url,HttpMethod.GET, requestEntity,String.class);

response contient 'body', 'headers' et 'statusCode'

pour obtenir statusCode: response.getStatusCode ();

1
santosh kumar

Il peut y avoir des cas d'utilisation légèrement plus délicats dans lesquels quelqu'un pourrait tomber (comme je l'ai fait). Considérer ce qui suit:

Prise en charge d'un objet Page afin de l'utiliser avec RestTemplate et ParameterizedTypeReference :

RestPageResponse:

import Java.util.ArrayList;
import Java.util.List;

import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

public class RestResponsePage<T> extends PageImpl<T>{

  private static final long serialVersionUID = 3248189030448292002L;

  public RestResponsePage(List<T> content, Pageable pageable, long total) {
    super(content, pageable, total);
  }

  public RestResponsePage(List<T> content) {
    super(content);
  }

  public RestResponsePage() {
    super(new ArrayList<T>());
  }

} 

Utiliser ParameterizedTypeReference donnera ce qui suit:

ParameterizedTypeReference<RestResponsePage<MyObject>> responseType = 
new ParameterizedTypeReference<RestResponsePage<MyObject>>() {};
HttpEntity<RestResponsePage<MyObject>> response = restTemplate.exchange(oauthUrl, HttpMethod.GET, entity, responseType);

Appeler #exchange :

HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            HttpEntity<?> entity = new HttpEntity<>(headers);

response = restTemplate.exchange("localhost:8080/example", HttpMethod.GET, entity, responseType);

Maintenant, voici la partie "difficile". 

Essayer d'appeler la variable getStatusCode de l'échange sera impossible car le compilateur ignorera malheureusement le type "voulu" de la variable response

En effet, les génériques sont implémentés via l’effacement des types, qui supprime toutes les informations relatives aux types génériques pendant la compilation (en savoir plus - source)

((ResponseEntity<RestResponsePage<MyObject>>) response).getStatusCode()

Dans ce cas, vous devez explicitement transtyper la variable dans la classe souhaitée pour obtenir la variable statusCode (et/ou d'autres attributs)!

0