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.
Related
I'm currently trying to do a POST request on Intercom API using unirest for java and It returns a server error 500 but when I do the same request with Postman it returns my desired results.
Sample code:
Map<String, String> headers = new HashMap<>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
headers.put("Authorization", "Bearer XXXXXXXXXXXXXXXXXXXXXXX");
HttpResponse response = Unirest
.post("https://api.intercom.io/conversations/search")
.headers(headers)
.body(requestBody)
.asObject(HashMap.class);
This is my request body
private Map<String, Object> getQueryValues(String field, String operator, Object value) {
Map<String, Object> map = new HashMap<>();
map.put("field", field);
map.put("operator", operator);
map.put("value", value);
return map;
}
private Map<String, Object> getRequestBody() {
List<Map<String, Object>> value = new ArrayList<>();
value.add(getQueryValues("updated_at", ">", 1590278400));
value.add(getQueryValues("source.delivered_as", "=", "admin_initiated"));
Map<String, Object> query = new HashMap<>();
query.put("operator", "AND");
query.put("value", value);
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("query", query);
return requestBody;
}
The problem turns out to be my UNIX date long value wherein the correct value should be the Epoch seconds. So from myDate.getTime() I changed it to myDate.toInstant().getEpochSecond().
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;
}
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
}
I am using multipart to fetch the pdf and object data from the service. I get the below error
java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters
in escape (%) pattern - For input string: "PD" at
java.net.URLDecoder.decode(URLDecoder.java:205) at
org.springframework.http.converter.FormHttpMessageConverter.read(FormHttpMessageConverter.java:186)
when invoking the service.
SERVICE :
#RequestMapping(value = "/getPDF", method = RequestMethod.GET,produces = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<MultiValueMap<String, Object>> getPDF(
#RequestParam String key,
HttpServletResponse response) {
MultiValueMap<String, Object> pdfResultMap = new LinkedMultiValueMap<String, Object>();
//Get the result
ByteArrayResource byteArrayResource = getPdf(); //Assign the PDF
//1) Build the first byte[] result
/* LinkedMultiValueMap<String, String> pdfMap = new LinkedMultiValueMap<>();
pdfMap.add("Content-disposition", "attachment;" );
pdfMap.add("Content-type", "application/pdf");*/
HttpHeaders xHeader2 = new HttpHeaders();
xHeader2.setContentType(MediaType.APPLICATION_PDF);
HttpEntity<ByteArrayResource> doc = new HttpEntity<ByteArrayResource>(byteArrayResource, xHeader2);
pdfResultMap.add("doc", doc);
// 2) Build the next
//Header
HttpHeaders xHeader = new HttpHeaders();
xHeader.setContentType(MediaType.APPLICATION_JSON);
// Get the result
Map<String, String> stringMap = new HashMap<String, String>();
//populate String map
HttpEntity<Map<String, String>> stringMapObject = new HttpEntity<Map<String, String>>(stringMap, xHeader);
pdfResultMap.add("stringMap", stringMapObject);
//3) Build the simple header
HttpHeaders xHeader1 = new HttpHeaders();
xHeader.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> titlePart = new HttpEntity<String>("pdftitle", xHeader1);
pdfResultMap.add("title", titlePart);
ResponseEntity<MultiValueMap<String, Object>> responseEntity = new ResponseEntity<MultiValueMap<String, Object>>(pdfResultMap, HttpStatus.OK);
return responseEntity;
}
CLIENT :
public getPdf() {
FormHttpMessageConverter formConverter = new FormHttpMessageConverter() {
#Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
if (clazz == MultiValueMap.class) {
return true;
}
return super.canRead(clazz, mediaType);
}
};
formConverter.setCharset(Charset.forName("UTF-8"));
List<HttpMessageConverter<?>> partConverters = new ArrayList<HttpMessageConverter<?>>();
partConverters.add(new ByteArrayHttpMessageConverter());
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
stringHttpMessageConverter.setWriteAcceptCharset(false);
partConverters.add(stringHttpMessageConverter);
partConverters.add(new ResourceHttpMessageConverter());
formConverter.setPartConverters(partConverters);
restTemplate.getMessageConverters().add(formConverter);
ResponseEntity<MultiValueMap> response = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET,entity, MultiValueMap.class);
}
I Tried adding :
List<MediaType> a = new ArrayList<MediaType>();
a.add(MediaType.APPLICATION_OCTET_STREAM);
a.add(MediaType.MULTIPART_FORM_DATA);
a.add(new MediaType("application","pdf"));
formConverter.setSupportedMediaTypes(a);
But the same error .
Anything I am missing here?
You try to read from FormHttpMessageConverter but the doc https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/FormHttpMessageConverter.html says
"In other words, this converter can read and write the "application/x-www-form-urlencoded" media type as MultiValueMap and it can also write (but not read) the "multipart/form-data" media type as MultiValueMap."
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;
}