2013-10-08 18 views
112

Desidero impostare il valore di Accept: in una richiesta che sto utilizzando utilizzando Spring RestTemplate.Come impostare un'intestazione "Accetta:" sulla richiesta Spring RestTemplate?

Ecco la mia richiesta primavera codice di gestione

@RequestMapping(
    value= "/uom_matrix_save_or_edit", 
    method = RequestMethod.POST, 
    produces="application/json" 
) 
public @ResponseBody ModelMap uomMatrixSaveOrEdit(
    ModelMap model, 
    @RequestParam("parentId") String parentId 
){ 
    model.addAttribute("attributeValues",parentId); 
    return model; 
} 

e qui è il mio client Java REST:

public void post(){ 
    MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>(); 
    params.add("parentId", "parentId"); 
    String result = rest.postForObject(url, params, String.class) ; 
    System.out.println(result); 
} 

Questo funziona per me; Ottengo una stringa JSON dal lato server.

La mia domanda è: come posso specificare l'intestazione Accept: (ad esempio application/json, application/xml, ...) e il metodo di richiesta (ad esempio GET, POST, ...) quando uso RestTemplate?

risposta

215

Suggerisco di utilizzare uno dei metodi exchange che accetta uno HttpEntity per il quale è anche possibile impostare HttpHeaders. (È inoltre possibile specificare il metodo HTTP che si desidera utilizzare.)

Per esempio,

RestTemplate restTemplate = new RestTemplate(); 
HttpHeaders headers = new HttpHeaders(); 
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); 

HttpEntity<String> entity = new HttpEntity<>("parameters", headers); 

restTemplate.exchange(url, HttpMethod.POST, entity, String.class); 

preferisco questa soluzione perché è fortemente tipizzato, cioè. exchange si aspetta uno HttpEntity.

Tuttavia, è anche possibile passare lo HttpEntity come argomento request a postForObject.

HttpEntity<String> entity = new HttpEntity<>("parameters", headers); 
restTemplate.postForObject(url, entity, String.class); 

Questo è indicato nello RestTemplate#postForObject Javadoc.

Il parametro request può essere un HttpEntity al fine di aggiungere ulteriori intestazioni HTTP alla richiesta.

+0

Se non si imposta l'accettare intestazioni, MediaType.APPLICATION_JSON è impostato di default in restTemplate.exchange(). –

75

È possibile impostare un intercettore "ClientHttpRequestInterceptor" nel tuo RestTemplate per evitare di impostare l'intestazione ogni volta che si invia una richiesta.

public class HeaderRequestInterceptor implements ClientHttpRequestInterceptor { 

     private final String headerName; 

     private final String headerValue; 

     public HeaderRequestInterceptor(String headerName, String headerValue) { 
      this.headerName = headerName; 
      this.headerValue = headerValue; 
     } 

     @Override 
     public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { 
      request.getHeaders().set(headerName, headerValue); 
      return execution.execute(request, body); 
     } 
    } 

Poi

List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>(); 
interceptors.add(new HeaderRequestInterceptor("Accept", MediaType.APPLICATION_JSON_VALUE)); 

RestTemplate restTemplate = new RestTemplate(); 
restTemplate.setInterceptors(interceptors); 
+5

Perché hai bisogno di HttpRequestWrapper qui? – nahab

+2

Accetto il tuo approccio meglio perché permette di usare Spring in un modo davvero primaverile, usando i metodi speciali 'postForObject' ecc., Invece di' exchange'. Grazie! – Daria

+0

Spring Boot 1.3 ha un HttpHeaderInterceptor, quindi non è necessario creare la nostra implementazione di ClientHttpRequestInterceptor. –

7

Se, come me, ha lottato per trovare un esempio che utilizza intestazioni con l'autenticazione di base e lo scambio API modello resto, questo è quello che finalmente lavorato fuori ...

private HttpHeaders createHttpHeaders(String user, String password) 
{ 
    String notEncoded = user + ":" + password; 
    String encodedAuth = Base64.getEncoder().encodeToString(notEncoded.getBytes()); 
    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(MediaType.APPLICATION_JSON); 
    headers.add("Authorization", "Basic " + encodedAuth); 
    return headers; 
} 

private void doYourThing() 
{ 
    String theUrl = "http://blah.blah.com:8080/rest/api/blah"; 
    RestTemplate restTemplate = new RestTemplate(); 
    try { 
     HttpHeaders headers = createHttpHeaders("fred","1234"); 
     HttpEntity<String> entity = new HttpEntity<String>("parameters", headers); 
     ResponseEntity<String> response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class); 
     System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody()); 
    } 
    catch (Exception eek) { 
     System.out.println("** Exception: "+ eek.getMessage()); 
    } 
} 
Problemi correlati