Faire des requêtes POST authentifiées avec Spring RestTemplate pour Android

J’ai une API RESTful avec laquelle j’essaie de me connecter via Android et RestTemplate. Toutes les demandes à l’API sont authentifiées avec l’authentification HTTP, en définissant les en-têtes de HttpEntity, puis en utilisant la méthode exchange() de RestTemplate.

Toutes les requêtes GET fonctionnent de cette façon, mais je ne peux pas comprendre comment accomplir les requêtes POST authentifiées. postForObject et postForEntity gèrent les POST, mais n’ont aucun moyen facile de définir les en-têtes d’authentification.

Donc, pour les GET, cela fonctionne très bien:

 HttpAuthentication httpAuthentication = new HttpBasicAuthentication("username", "password"); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setAuthorization(httpAuthentication); HttpEntity httpEntity = new HttpEntity(requestHeaders); MyModel[] models = restTemplate.exchange("/api/url", HttpMethod.GET, httpEntity, MyModel[].class); 

Mais les POST ne fonctionnent apparemment pas avec exchange() car il n’envoie jamais les en-têtes personnalisés et je ne vois pas comment définir le corps de la requête en utilisant exchange() .

Quel est le moyen le plus simple de créer des requêtes POST authentifiées à partir de RestTemplate?

Ok a trouvé la réponse. exchange() est le meilleur moyen. Curieusement, la classe HttpEntity n’a pas de méthode setBody() (elle a getBody() ), mais il est toujours possible de définir le corps de la requête, via le constructeur.

 // Create the request body as a MultiValueMap MultiValueMap body = new LinkedMultiValueMap(); body.add("field", "value"); // Note the body object as first parameter! HttpEntity httpEntity = new HttpEntity(body, requestHeaders); MyModel model = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class); 

Une approche légèrement différente:

 MultiValueMap headers = new LinkedMultiValueMap(); headers.add("HeaderName", "value"); headers.add("Content-Type", "application/json"); RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); HttpEntity request = new HttpEntity(objectToPass, headers); restTemplate.postForObject(url, request, ClassWhateverYourControllerReturns.class); 

J’étais récemment confronté à un problème lorsque j’essayais d’obtenir une authentification après avoir effectué un appel REST à partir de Java, et bien que les réponses à ce sujet (et aux autres threads) aient aidé, travail.

Ce qui a fonctionné pour moi était l’encodage des informations d’identification dans Base64 et leur ajout en tant qu’en-têtes d’autorisation de base. Je les ai ensuite ajoutés en tant que HttpEntity à restTemplate.postForEntity , ce qui m’a donné la réponse dont j’avais besoin.

Voici la classe que j’ai écrite pour cela en entier (extension de RestTemplate):

 public class AuthorizedRestTemplate extends RestTemplate{ private Ssortingng username; private Ssortingng password; public AuthorizedRestTemplate(Ssortingng username, Ssortingng password){ this.username = username; this.password = password; } public Ssortingng getForObject(Ssortingng url, Object... urlVariables){ return authorizedRestCall(this, url, urlVariables); } private Ssortingng authorizedRestCall(RestTemplate restTemplate, Ssortingng url, Object... urlVariables){ HttpEntity request = getRequest(); ResponseEntity entity = restTemplate.postForEntity(url, request, Ssortingng.class, urlVariables); return entity.getBody(); } private HttpEntity getRequest(){ HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Basic " + getBase64Credentials()); return new HttpEntity(headers); } private Ssortingng getBase64Credentials(){ Ssortingng plainCreds = username + ":" + password; byte[] plainCredsBytes = plainCreds.getBytes(); byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); return new Ssortingng(base64CredsBytes); } } 

Très utile j’ai eu un scénario légèrement différent où la requête xml était elle-même le corps du POST et non un param. Pour cela, le code suivant peut être utilisé – Publier en tant que réponse au cas où une autre personne ayant un problème similaire en bénéficierait.

  final HttpHeaders headers = new HttpHeaders(); headers.add("header1", "9998"); headers.add("username", "xxxxx"); headers.add("password", "xxxxx"); headers.add("header2", "yyyyyy"); headers.add("header3", "zzzzz"); headers.setContentType(MediaType.APPLICATION_XML); headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML)); final HttpEntity httpEntity = new HttpEntity( MyXmlbeansRequestDocument.Factory.parse(request), headers); final ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity,MyXmlbeansResponseDocument.class); log.info(responseEntity.getBody());