Java Springboot Restemplate response 500 while postman is not - java

I send a post with restTemplate, same params with postman but return 500 while postman is working, thanks for help so much.
Example link:
https://www.baeldung.com/spring-resttemplate-post-json
public void getRestTemplate(String user, String pass) {
RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Arrays.asList(new MediaType[]{MediaType.ALL}));
converter.setObjectMapper(objectMapper());
return restTemplateBuilder
.messageConverters(converter)
.basicAuthorization(user, pass)
.setConnectTimeout(120000)
.setReadTimeout(120000)
.build();
}
public void abc() {
String user = "...";
String pass = "...";
String url = "...";
RestTemplate restTemplate = getRestTemplate(user, pass);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
JSONObject jsonObject = new JSONObject();
JSONArray params = new JSONArray();
params.put("a");
params.put("b");
params.put(false);
Map<String, String> map = new HashMap<>();
jsonObject.put("jsonrpc", "2.0");
jsonObject.put("method", "x");
jsonObject.put("params", params);
jsonObject.put("id", 1);
ClientHttpRequestFactory requestFactory = new
HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());
restTemplate.setRequestFactory(requestFactory);
HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), headers);
String _response = restTemplate.postForObject(url, request, String.class);
}
/*
json format:
{
"jsonrpc": "2.0",
"method": "x",
"params": [
"a", "b", false
],
"id": 1
}
*/
Postman status 200:
{
"result": null,
"error": null,
"id": 1
}

Related

401 unauthorized : [no body] with root cause in JAVA Spring

I'm creating my first REST API using JAVA Spring and when I'm making a rest call to an external API, I get
401 Unauthorized: [no body]
I think my problem is here:
requestParams.add("Grant_type", "client_credentials");
I saw some questions related to this but none well able to solve my problem.
Spring REST template - 401 Unauthorized error
Spring Boot Callable - 401 Unauthorized: [no body]
JAVA code:
public String getAuth(String client_id, String app_secret) {
String auth = client_id + ":" + app_secret;
return Base64.getEncoder().encodeToString(auth.getBytes());
}
#GetMapping(value = "/token")
public Object generateAccessToken() {
String auth = this.getAuth(
"CLIENT_ID",
"APP_SECRET"
);
RestTemplate restTemplate = new RestTemplate();
String base = "https://external-api.com";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Basic " + auth);
MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
requestParams.add("Grant_type", "client_credentials");
ResponseEntity<Object> response = restTemplate.postForEntity(
base + "/v1/oauth2/token",
requestParams,
Object.class,
headers
);
return response.getBody();
}
Here's the solution to my own question.
This is what I had to change;
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("grant_type", "client_credentials");
HttpEntity<?> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.postForEntity(
base +"/v1/oauth2/token",
request,
String.class
);
Here's the final solution:
public String generateAccessToken() {
String base = "example-api.com";
String auth = this.getAuth(
"client id",
"app_id"
);
// create an instance of RestTemplate
RestTemplate restTemplate = new RestTemplate();
// create headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Basic " + auth);
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("grant_type", "client_credentials");
HttpEntity<?> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.postForEntity(
base +"/v1/oauth2/token",
request,
String.class
);
// check response
if (response.getStatusCode() == HttpStatus.OK) {
System.out.println("Request Successful");
System.out.println(response.getBody());
} else {
System.out.println("Request Failed");
System.out.println(response.getStatusCode());
}
JSONObject object = new JSONObject(response.getBody());
return object.getString("access_token");
}

How to Get particular value from restTemplate in springboot?

I have an api with given request body and response , now I have to call restTemplate for it and get particular response from it
This is my requestBody ->
{"ids":["MS8B50FHS"]}
And this is my response ->
{
"status": 200,
"success": true,
"message": "detail found!",
"data": {
"MS8B50FHS": {
"ids": "MS8B50FHS",
"creditTerm": "Credit 45 days"
}
}
}
Now for this I need to get creditterm by calling a restTemplate
#Override
public String findByUniqueSupplierId (String ids){
final String url = BaseUrl ;
HttpHeaders headers = new HttpHeaders();
HttpEntity<Object> requestEntity = new HttpEntity<>(headers);
Map<String, List<String>> params = new HashMap<>();
params.put("ids", Collections.singletonList(ids));
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> object = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class , params);
return object.getBody();
}
I was trying something like this but not getting result
You can assign JSON data to objects using the fromJson() method from the Gson library.
String body = object.getBody();
Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(body, HashMap.class);
Map<String, Object> data = (Map<String, Object>) map.get("data");
Map<String, Object> creditTerm = (Map<String, Object>) data.get("MS8B50FHS");
String creditTermValue = creditTerm.get("creditTerm").toString();
System.out.println(creditTermValue);
Could be refactored.

Post Json Array in Json Object via RestTemplate in Spring Boot

Im trying to post an array in a json object using RestTemplate
{
"update": {
"name": "xyz",
"id": "C2",
"Description": "aaaaaa",
"members": ["abc", "xyz"]
}
}
Here is my PostMapping Controller
#PostMapping(value = "/update")
public Update update(#RequestBody Update update) {
String url = "";
HttpHeaders headers = createHttpHeaders("username", "passowrd");
JSONObject jsonObject = new JSONObject();
jsonObject.put("update", update);
HttpEntity<JSONObject> request = new HttpEntity<>(jsonObject, headers);
ResponseEntity<Update> update = restTemplate.exchange(url, HttpMethod.POST,request, Update.class);
return update.getBody();
}
And this my POJO
public class Update {
private String name;
private String id;
private String Descripion;
private List<String> members;
}
And Im getting 500
{
"timestamp": "2020-03-13T06:31:21.822+0000",
"status": 500,
"error": "Internal Server Error",
"message": "No HttpMessageConverter for org.json.JSONObject and content type \"application/json\""
}
Try to configure your RestTemplate with a Json Message Converter.
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
You may refer this blog post for a detailed explanation
https://www.baeldung.com/spring-httpmessageconverter-rest
And then perform your rest call as below.You will no longer need to explicitly create a Json Object.
String url = "";
HttpEntity<Update> request = new HttpEntity<>(update, headers);
ResponseEntity<Update> firewallGroupUpdate = restTemplate.exchange(url, HttpMethod.POST, request, Update.class);
return firewallGroupUpdate.getBody();
Changed resttemplate.exchange to resttemplate.postForObject.
And also changed the method to return String.
public String groupUpdate(#RequestBody String groupUpdate) {
String url = "";
HttpHeaders headers = createHeaders("username","password");
headers.setContentType(MediaType.APPLICATION_JSON);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpEntity<String> requestEntity = new HttpEntity<String>(groupUpdate, headers);
String response = restTemplate.postForObject(url,requestEntity,String.class);
return response;
}

How to do GET API Request with URL params?

Client client = ClientBuilder.newClient();
urlApi="https://localhost:123/demo/api/v1/rows/search?";
WebTarget webTarget = client.target(urlApi);
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
webTarget.queryParam(entry.getKey(), entry.getValue());
}
webTarget.queryParam("searchConditions",webTarget.queryParam("mobileNo","+9999999999"));
Invocation.Builder builder = webTarget.request();
builder.header("id", "ABC");
String asB64 = Base64.getEncoder().encodeToString("ABC:PWD".getBytes("utf-8"));
logger.debug("Calling API "+urlApi);
builder.header("Authorization", "Basic "+asB64);
builder.header("Content-type", MediaType.APPLICATION_JSON);
response = builder.get();
responseData = response.readEntity(String.class);
System.out.println(responseData);
I am trying to do GET request with searchCondition as Key and value as {mobileNo="+919999999999"}, I am unable to get this to work.
Apart from that, how can I print the Request "Headers" along with "Query params"? Thank you in advance
I think you need to encode the value inputs, something like this:
webTarget.queryParam("searchCondition", URLEncoder.encode("{mobileNo=\"+919999999999\"}", StandardCharsets.UTF_8.toString()));
UDPATE:
Example of the rest client with Spring:
#Test
public void testStack() throws Exception {
RestTemplate rest = new RestTemplate();
String fooResourceUrl="http://localhost:8080/usersParam?";
RestTemplate restTemplate = new RestTemplate();
String parameter = "{mobileNo=\"+919999999999\"}";
ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "parameter=" + URLEncoder.encode(parameter, StandardCharsets.UTF_8.toString() ), String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
And this would be the rest service:
#RequestMapping(method = RequestMethod.GET, value="/usersParam")
public User getUsersInfo(#RequestParam String parameter) throws UnsupportedEncodingException {
System.out.println(URLDecoder.decode(parameter, StandardCharsets.UTF_8.toString() ));
return null;
}

Spring mapping JSON to java POJO

I have API which returns JSON in this format:
[
{ "shrtName": "abc", "validFrom": "2016-10-23", "name": "aaa", "version": 1 },
{ "shrtName": "def", "validFrom": "2016-11-20", "name": "bbb", "version": 1 },
{ "shrtName": "ghi", "validFrom": "2016-11-22", "name": "ccc", "version": 1 }
]
I have this code which reads API and returns it as a String. But I want to read this API and map it into the Java POJO class.
public String downloadAPI(){
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("API-Key", "4444444-3333-2222-1111-88888888");
HttpEntity<?> requestEntity = new HttpEntity<Object>(headers);
String URL = "https://aaaaaaa.io/api/v1/aaaaaaaaa?date=2015-04-04;
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
ResponseEntity<String> response = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, String.class);
return response.getBody();
}
My questions:
1) Format of POJO?
2) Changes in my method (return type POJO instead of String)
Your JSON is an array that's why []
Create POJO
public class MyPOJO {
private String shrtName;
private Date validFrom;
private String name;
private int version;
}
Remove message converter and refactor restTemplate exchange method to
ResponseEntity<MyPOJO[].class> response = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, MyPOJO[].class);
This is generic function that I use for GET requests
public <T> T getRequestAndCheckStatus(final String url, final Class<T> returnTypeClass,
final List<MediaType> mediaTypes,
final Map<String, String> headerParams,
final Map<String, Object> queryParams) throws Exception {
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(mediaTypes);
setHeaderParamsIfExists(headers, headerParams);
final HttpEntity<String> requestEntity = new HttpEntity<>(headers);
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
setQueryParamsIfExists(uriBuilder, queryParams);
final ResponseEntity<T> entity = restTemplate
.exchange(getUrl(uriBuilder),
HttpMethod.GET,
requestEntity,
returnTypeClass);
Assert.assertEquals(HttpStatus.OK, entity.getStatusCode());
return entity.getBody();
}
private void setHeaderParamsIfExists(HttpHeaders headers, Map<String, String> headerParams) {
if(headerParams != null && !headerParams.isEmpty())
headerParams.entrySet()
.forEach(entry -> headers.set(entry.getKey(), entry.getValue()));
}
private void setQueryParamsIfExists(UriComponentsBuilder uriBuilder, Map<String, Object> queryParams) {
if(queryParams != null && !queryParams.isEmpty())
queryParams.entrySet()
.forEach(entry -> uriBuilder.queryParam(entry.getKey(), entry.getValue()));
}
private URI getUrl(UriComponentsBuilder uriBuilder) {
return uriBuilder.build().encode().toUri();
}
In your case you would call it by
getRequestAndCheckStatus("https://aaaaaaa.io/api/v1/aaaaaaaaa", MyPOJO[].class,
Collections.singletonList(MediaType.APPLICATION_JSON_UTF8),
new HashMap<String, String>(){{ put("API-Key", "4444444-3333-2222-1111-88888888"); }}),
new HashMap<String, Object>(){{ put("Date", "2015-04-04"); }});
Additionaly, for Date I recommend to use long and then in controller parse it to Date. I see that you use https protocol, have you configured certificate ?
Create a pojo with those atrributes and use jackson for convert from json String to your pojo.
public class MapClass {
private String shrtName;
private Date validFrom;
private String name;
private int version;
}

Categories