1
votes

I am developing an application Java + Salesforce and calling salesforce services using the Spring RestTemplate API, but seems getting some error. Any help ?

public class RestTemplateExample {

    final static String TOKEN_URL = "https://ap5.salesforce.com/services/oauth2/token";

    public static void main(String[] args) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("client_secret", "XXXXXXXXX");
        headers.add("client_id", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        headers.add("grant_type", "password");
        headers.add("username", "[email protected]");
        headers.add("password", "XXXXXXXXXXXX");
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

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

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> result = restTemplate.exchange(TOKEN_URL, HttpMethod.POST, entity, String.class);
        System.out.println("TOKEN DETAILS :: "+result.getBody());
    }
}

When I checked through postman it works fine.

2017-10-14 18:40:35 DEBUG o.s.web.client.RestTemplate - Created POST request for "https://ap5.salesforce.com/services/oauth2/token"
2017-10-14 18:40:35 DEBUG o.s.web.client.RestTemplate - Setting request Accept header to [text/plain, application/json, application/*+json, */*]
2017-10-14 18:40:35 DEBUG o.s.web.client.RestTemplate - Writing [] using [org.springframework.http.converter.StringHttpMessageConverter@2141a12]
2017-10-14 18:40:37 DEBUG o.s.web.client.RestTemplate - POST request for "https://ap5.salesforce.com/services/oauth2/token" resulted in 400 (Bad Request); invoking error handler
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:78)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
    at com.example.RestTemplateExample.main(RestTemplateExample.java:29)

https://ap5.salesforce.com/services/oauth2/token?client_id=XXXXXXXX&client_secret=XXXXXXXXXXX&username=XXXXXXXXXXXXX&password=XXXXXXXXXXXX&grant_type=password

enter image description here

2

2 Answers

1
votes

This needs to be implemented like below which works fine.

// create the Map of the MultiValueMap
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("grant_type", "password");
map.add("client_id", "XX");
map.add("client_secret", "XXX");
map.add("username", "XX");
map.add("password", "XXX");

// RestTemplate
RestTemplate restTemplate = new RestTemplate();
Map<String, String> token = restTemplate.postForObject(TOKEN_URL, map, Map.class);
System.out.println("--------------------------------------------");
System.out.println("Access Token  :: "+token.get("access_token"));
System.out.println("Instance Url  :: "+token.get("instance_url"));
System.out.println("Id  :: "+token.get("id"));
System.out.println("Token_Type  :: "+token.get("token_type"));
System.out.println("Signature  :: "+token.get("signature"));
System.out.println("--------------------------------------------");

The token url would be the below.

final static String TOKEN_URL = "https://login.salesforce.com/services/oauth2/token";

Here is the output for reference:

--------------------------------------------
Access Token  :: 00D7F0000001I8v!ARgAQB7R8VtkU8QbUYHfdBjytHPATIDYmMKkPt7sunvUW4DeM2t.c.wFDJ0.k0uNPogX5aPWIrL_lHkrbfNai_t.byjjRCy_
Instance Url  :: https://ap5.salesforce.com
Id  :: https://login.salesforce.com/id/00D7F0000001I8vUAE/0057F000000l2bgQAA
Token_Type  :: Bearer
Signature  :: veYhITIlhqf9SJqvBAZ4PKiLh1sj9at13D3m44TnBxw=
--------------------------------------------
0
votes

You are trying to send your query string parameters as headers (which is not the same). The following code will be equal to your test in Postman

public class RestTemplateExample {

    final static String TOKEN_URL = "https://ap5.salesforce.com/services/oauth2/token";

    public static void main(String[] args) {

    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(TOKEN_URL)
        .queryParam("client_secret", "XXXXXXXXX")
        .queryParam("client_id", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
        .queryParam("grant_type", "password")
        .queryParam("username", "[email protected]")
        .queryParam("password", "XXXXXXXXXXXX");

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

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

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> result = restTemplate.exchange(
            builder.build().encode().toUri(), 
            HttpMethod.POST, 
            entity, String.class
        );
        System.out.println("TOKEN DETAILS :: "+result.getBody());
    }
}