Envoi d’une requête GET avec les en-têtes d’authentification à l’aide de restTemplate

Je dois récupérer une ressource de mon serveur en envoyant une requête GET avec certains en-têtes d’autorisation à l’aide de RestTemplate.

Après avoir parcouru les documents, j’ai remarqué qu’aucune des méthodes GET n’accepte les en-têtes en tant que paramètre, et la seule façon d’envoyer des en-têtes tels que accepter et autoriser consiste à utiliser la méthode d’ échange .

Comme il s’agit d’une action très basique, je me demande si je manque quelque chose et qu’il existe un autre moyen plus facile de le faire?

Vous ne manquez rien. RestTemplate#exchange(..) est la méthode appropriée à utiliser pour définir les en-têtes de requête.

Voici un exemple (avec POST, mais changez simplement cela en GET et utilisez l’entité que vous voulez).

Voici un autre exemple.

Notez qu’avec un GET, votre entité de demande n’a pas besoin de contenir quoi que ce soit (à moins que votre API ne l’attende, mais cela irait à l’encontre des spécifications HTTP). Ce peut être une chaîne vide.

Vous pouvez utiliser postForObject avec une HttpEntity . Cela ressemblerait à ceci:

 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Authorization", "Bearer "+accessToken); HttpEntity entity = new HttpEntity(requestJson,headers); Ssortingng result = restTemplate.postForObject(url, entity, Ssortingng.class); 

Dans une requête GET, vous n’envoyez généralement pas de corps (c’est autorisé, mais cela ne sert à rien). La façon d’append des en-têtes sans câbler différemment le RestTemplate consiste à utiliser directement les méthodes d’ exchange ou d’ execute . Les raccourcis get ne supportent pas la modification d’en-tête.

L’asymésortinge est un peu étrange au premier abord, peut-être que cela sera corrigé dans les futures versions de Spring.

Voici un exemple très simple avec l’authentification de base, les en-têtes et la gestion des exceptions …

 private HttpHeaders createHttpHeaders(Ssortingng user, Ssortingng password) { Ssortingng notEncoded = user + ":" + password; Ssortingng encodedAuth = "Basic " + Base64.getEncoder().encodeToSsortingng(notEncoded.getBytes()); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.add("Authorization", encodedAuth); return headers; } private void doYourThing() { Ssortingng theUrl = "http://blah.blah.com:8080/rest/api/blah"; RestTemplate restTemplate = new RestTemplate(); try { HttpHeaders headers = createHttpHeaders("fred","1234"); HttpEntity entity = new HttpEntity("parameters", headers); ResponseEntity response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, Ssortingng.class); System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody()); } catch (Exception eek) { System.out.println("** Exception: "+ eek.getMessage()); } } 

Toutes ces réponses semblent être incomplètes et / ou kludges. En regardant l’interface RestTemplate, il semble certain que ClientHttpRequestFactory doit être injecté, et que requestFactory sera utilisé pour créer la demande, y compris les personnalisations des parameters d’en-tête, de corps et de requête.

Vous avez besoin soit d’un ClientHttpRequestFactory universel pour l’injecter dans un seul RestTemplate partagé, soit vous devez obtenir une nouvelle instance de modèle via le new RestTemplate(myHttpRequestFactory) .

Malheureusement, la création d’une telle fabrique ne semble pas sortingviale, même si vous souhaitez simplement définir un seul en-tête d’autorisation, ce qui est assez frustrant compte tenu de ce qui est probablement le cas, mais au moins, il est facile à utiliser si, par exemple, , votre en-tête d’autorisation peut être créé à partir des données contenues dans un object d’ Authorization Spring-Security, puis vous pouvez créer une fabrique qui définit le AuthorizationHeader sortant sur chaque demande en effectuant SecurityContextHolder.getContext().getAuthorization() puis en SecurityContextHolder.getContext().getAuthorization() l’en-tête avec contrôles nuls, le cas échéant. Maintenant, tous les appels de repos sortants effectués avec ce RestTemplate auront l’en-tête d’autorisation correct.

Sans mettre davantage l’accent sur le mécanisme HttpClientFactory, fournissant des classes de base simples à surcharger pour les cas courants comme l’ajout d’un seul en-tête aux requêtes, la plupart des méthodes conviviales de RestTemplate finissent par être une perte de temps. utilisé.

J’aimerais voir quelque chose de simple comme celui-ci disponible

 @Configuration public class MyConfig { @Bean public RestTemplate getRestTemplate() { return new RestTemplate(new AbstractHeaderRewritingHttpClientFactory() { @Override public HttpHeaders modifyHeaders(HttpHeaders headers) { headers.addHeader("Authorization", computeAuthSsortingng()); return headers; } public Ssortingng computeAuthSsortingng() { // do something better than this, but you get the idea return SecurityContextHolder.getContext().getAuthorization().getCredential(); } }); } } 

Pour le moment, l’interface de ClientHttpRequestFactory disponible est plus difficile à interagir que cela. Encore mieux serait un wrapper abstrait pour les implémentations d’usine existantes, ce qui les ferait ressembler à un object plus simple comme AbstractHeaderRewritingRequestFactory dans le but de ne remplacer que cette seule fonctionnalité. À l’heure actuelle, ils ont un but très général, de sorte que même l’écriture de ces enveloppes est une recherche complexe.