Making authenticated POST requests with Spring RestTemplate for Android
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 MultiValueMapMultiValueMap<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);
I was recently dealing with an issue when I was trying to get past authentication while making a REST call from Java, and while the answers in this thread (and other threads) helped, there was still a bit of trial and error involved in getting it working.
What worked for me was encoding credentials in Base64
and adding them as Basic Authorization headers. I then added them as an HttpEntity
to restTemplate.postForEntity
, which gave me the response I needed.
Here's the class I wrote for this in full (extending 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); }}