I have a RESTful API I'm trying to connect with via Android and RestTemplate. All requests to the API are authenticated with HTTP Authentication, through setting the headers of the HttpEntity and then using RestTemplate's exchange()
method.
All GET requests work great this way, but I cannot figure out how to accomplish authenticated POST requests. postForObject
and postForEntity
handle POSTs, but have no easy way to set the Authentication headers.
So for GETs, this works great:
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);
But POSTs apparently don't work with exchange()
as it never sends the customized headers and I don't see how to set the request body using exchange()
.
What is the easiest way to make authenticated POST requests from RestTemplate?
To enable basic authentication in RestTemplate for outgoing rest requests, we shall configure CredentialsProvider into HttpClient API. This HttpClient will be used by RestTemplate to send HTTP requests to backend rest apis. In this example, we are creating a Junit test which invokes a basic auth secured rest api.
Setting bearer token for a GET request RestTemplate restTemplate = new RestTemplate(); String customerAPIUrl = "http://localhost:9080/api/customer"; HttpHeaders headers = new HttpHeaders(); headers. set("Authorization", "Bearer " + accessToken); //accessToken can be the secret key you generate. headers.
Consuming POST API by using RestTemplate - exchange() method Assume this URL http://localhost:8080/products returns the response shown below, we are going to consume this API response by using the Rest Template. Autowired the Rest Template Object. Use the HttpHeaders to set the Request Headers.
Here, we'll try to send POST requests to the Person API by using the POST methods provided by the RestTemplate: postForObject, postForEntity, and postForLocation.
Ok found the answer. exchange()
is the best way. Oddly the HttpEntity
class doesn't have a setBody()
method (it has getBody()
), but it is still possible to set the request body, via the constructor.
// 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); ResponseEntity<MyModel> response = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class);
Slightly different approach:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With