2012-04-27 32 views
34

Ho un'API RESTful che sto cercando di connettermi tramite Android e RestTemplate. Tutte le richieste all'API sono autenticate con l'autenticazione HTTP, tramite l'impostazione delle intestazioni di HttpEntity e quindi utilizzando il metodo exchange() di RestTemplate.Esecuzione di richieste POST autenticate con Spring RestTemplate per Android

Tutte le richieste GET funzionano in questo modo, ma non riesco a capire come eseguire richieste POST autenticate. postForObject e postForEntity gestiscono i POST, ma non hanno un modo semplice per impostare le intestazioni di autenticazione.

Così per GET, questa grande opera:

HttpAuthentication httpAuthentication = new HttpBasicAuthentication("username", "password"); 
HttpHeaders requestHeaders = new HttpHeaders(); 
requestHeaders.setAuthorization(httpAuthentication); 

HttpEntity<?> httpEntity = new HttpEntity<Object>(requestHeaders); 

MyModel[] models = restTemplate.exchange("/api/url", HttpMethod.GET, httpEntity, MyModel[].class); 

Ma POST a quanto pare non funzionano con exchange() quanto mai invia le intestazioni personalizzate e non vedo come impostare il corpo richiesta utilizzando exchange().

Qual è il modo più semplice per eseguire richieste POST autenticate da RestTemplate?

+1

requestHeaders.setAuthorization (httpAuthentication) .. il suo metodo undefined..no come setAuthorization .. – DEADEND

risposta

75

Ok ha trovato la risposta. exchange() è il modo migliore. Stranamente la classe HttpEntity non ha un metodo setBody() (ha getBody()), ma è ancora possibile impostare il corpo della richiesta, tramite il costruttore.

// Create the request body as a MultiValueMap 
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();  

body.add("field", "value"); 

// Note the body object as first parameter! 
HttpEntity<?> httpEntity = new HttpEntity<Object>(body, requestHeaders); 

MyModel model = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class); 
+2

Si genera un errore TypeMismatch Tipo non corrispondente: non può convertire da ResponseEntity a MyModel .. Credo che dovrebbe essere ResponseEntity modello = restTemplate.exchange ("/ api/url", HttpMethod.POST, httpEntity, MyModel.class); – Sid

+0

'MyModel myModel = restTemplate.exchange (completeServiceUrl, HttpMethod.GET, request, MyModel.class) .getBody()' aiuterà a risolvere il problema menzionato – Isank

+0

THANKS. Questo mi è costato due ore, finché non sono inciampato nel tuo post. – guenhter

7

Molto utile ho avuto uno scenario leggermente diverso dove la richiesta XML è stato in sé il corpo del post e non un param. Per questo è possibile utilizzare il seguente codice: Pubblicare come risposta nel caso in cui altri utenti con problemi simili possano trarne beneficio.

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<MyXmlbeansRequestDocument> httpEntity = new HttpEntity<MyXmlbeansRequestDocument>(
      MyXmlbeansRequestDocument.Factory.parse(request), headers); 
    final ResponseEntity<MyXmlbeansResponseDocument> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity,MyXmlbeansResponseDocument.class); 
    log.info(responseEntity.getBody()); 
14

approccio leggermente diverso:

MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>(); 
headers.add("HeaderName", "value"); 
headers.add("Content-Type", "application/json"); 

RestTemplate restTemplate = new RestTemplate(); 
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 

HttpEntity<ObjectToPass> request = new HttpEntity<ObjectToPass>(objectToPass, headers); 

restTemplate.postForObject(url, request, ClassWhateverYourControllerReturns.class); 
+2

Da dove proviene ObjectToPass –

+0

@Ismail Iqbal: può essere qualsiasi oggetto con informazioni che è necessario passare (ad esempio, Person privato john = Person ("John", 24);). Sarà convertito in payload json e inviato al server tramite il corpo della richiesta – Andrey

7

Recentemente sono stato a che fare con un problema quando stavo cercando di ottenere l'autenticazione passato, mentre si effettua una chiamata REST da Java, e mentre le risposte in questa discussione (e altri thread) ha aiutato, c'era ancora un po 'di prove ed errori coinvolti nel farlo funzionare.

Ciò che ha funzionato per me era la codifica delle credenziali in Base64 e l'aggiunta come intestazioni di autorizzazione di base. Poi li ho aggiunti come HttpEntity a restTemplate.postForEntity, che mi ha dato la risposta di cui avevo bisogno.

Ecco la classe che ho scritto per questo in pieno (che si estende RestTemplate):

public class AuthorizedRestTemplate extends RestTemplate{ 

    private String username; 
    private String password; 

    public AuthorizedRestTemplate(String username, String password){ 
     this.username = username; 
     this.password = password; 
    } 

    public String getForObject(String url, Object... urlVariables){ 
     return authorizedRestCall(this, url, urlVariables); 
    } 

    private String authorizedRestCall(RestTemplate restTemplate, 
      String url, Object... urlVariables){ 
     HttpEntity<String> request = getRequest(); 
     ResponseEntity<String> entity = restTemplate.postForEntity(url, 
       request, String.class, urlVariables); 
     return entity.getBody(); 
    } 

    private HttpEntity<String> getRequest(){ 
     HttpHeaders headers = new HttpHeaders(); 
     headers.add("Authorization", "Basic " + getBase64Credentials()); 
     return new HttpEntity<String>(headers); 
    } 

    private String getBase64Credentials(){ 
     String plainCreds = username + ":" + password; 
     byte[] plainCredsBytes = plainCreds.getBytes(); 
     byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); 
     return new String(base64CredsBytes); 
    } 
} 
Problemi correlati