Deserialize json array where attribute value is array java - java

I know this is very basic, but I have a problem with deserializing json using jackson when the format is like this :
I created a class Person with id, name and place and tried to read the results from API call using jackson (using the #JsonProperty annotation), but when I debug the persons variable is null:
json body:
{ people:[
{
"id":"0",
"name":"Bob",
"place":"Colorado",
},
{
"id":"1",
"name":"John",
"place":"Chicago",
},
{
"id":"2",
"name":"Marry",
"place":"Miami",
}
]}
RequestEntity<Void> reqEntity = RequestEntity.get(new URI(url))
.accept(MediaType.APPLICATION_JSON)
.build();
ResponseEntity<List<Person>> persons = template.exchange(reqEntity, new ParameterizedTypeReference<List<Person>>() {});

You should wrap your List<Person> in another Response object, which has a people field, containing your list:
public class PeopleResponse {
private List<Person> people;
// getter and setter
}
Then you can change your ResponseEntity according to that:
ResponseEntity<PeopleResponse> response = template.exchange(reqEntity, new ParameterizedTypeReference<PeopleResponse>() {});
List<Person> people = response.getBody().getPeople();

Related

How to serialize Map<String, Map<MetricName, ? extends Metric>> to generate Metrics Json Object

I've tried to serialize my Map<String, Map<MetricName, ? extends Metric>> object using Gson but I'm getting JSON String response.And also I have the metrics value and name in that inner Map<MetricName, ? extends Metric> Here is my code looks like:
#GetMapping(path = "/showRawKafkaMetrics", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public List<String> getMetrics() throws IOException, ClassNotFoundException {
List<String> list = new ArrayList<>();
Gson gson = new Gson();
for (MessageListenerContainer container : kafkaListenerEndpointRegistry.getListenerContainers()){
list.add(gson.toJson(container.metrics()));
}
return list;
}
I'm getting JSON String response
Well, you are returning List<String>
If you want Spring to return JSON, then add a response mapping for application/json (which you did; produces = MediaType.APPLICATION_JSON_VALUE)
If you're expecting some response like
{
"foo": {
"metric": "bar"
}
}
Then you cannot return List<?> since that is an Object/Map.
You should ideally have a concrete Response model class for each returned type.

deserializing a list of objects json object with jackson - cannot deserialize instance out of start_array token

I am reading a JSON response back from Mailchimp's Mandrill API with jackson. The response is a bit unconventional for an API response in that it includes handlebars inside of square brackets - a list of objects. The other stack overflow discussions around this error pertain to API responses that are not in a list.
[
{
"email": "gideongrossman#gmail.com",
"status": "sent",
"_id": "6c6afbd3702f4fdea8de690c284f5898",
"reject_reason": null
}
]
I am getting this error...
2019-07-06 22:41:47.916 DESKTOP-2AB6RK0 core.RestClient 131222 ERROR com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `core.user.MandrillWrapper$TemplatedEmailResponse` out of START_ARRAY token
What is the correct way to define this response object?
I have tried defining the response with the following types. None worked.
public static class TemplatedEmailResponse {
public LinkedHashMap<String, String>[] response;
}
public static class TemplatedEmailResponse {
public ArrayList<LinkedHashMap<String, String>> response;
}
#milchalk...How exactly can I use your objectmapper suggestion with the way I am currently calling the API and handling the response?
TemplatedEmailResponseList ret = getClient("messages/send-template.json").post(mandrillPayload,
TemplatedEmailResponseList.class);
where
public <T> T post(Object payload, Class<T> responseType) {
try {
Entity<Object> entity = Entity.entity(payload, MediaType.APPLICATION_JSON);
T t = client.target(url).request(MediaType.APPLICATION_JSON).post(entity, responseType);
return t;
} catch (Throwable t) {
logError(t);
throw t;
} finally {
client.close();
}
}
You can deserialize this json directly to List of your Pojo classes.
Given model class :
public class TemplatedEmailResponse {
private String email;
private String status;
private String _id;
private String reject_reason;
//getters setters
}
You can deserialize this json using TypeReference for List<TemplatedEmailResponse> :
ObjectMapper mapper = new ObjectMapper();
TypeReference<List<TemplatedEmailResponse>> typeRef = new TypeReference<List<TemplatedEmailResponse>>() {};
List<TemplatedEmailResponse> list = mapper.readValue(json, typeRef);
Where json variable represents the json string in this case.

how can i consume JSON response with many JsonProperty name in java

i'm trying to consume a Json response using RestTemplate in java with Jackson annotations, and i have a resource that have many name properties like so:
{
-name1:{
id:2,
price:12,
name:"Bob:
},
-name2:{
id:111,
price:1.1,
name:"Ron:
},
-name3:{
id:10,
price:33,
name:"jhon:
},
}
and the list go on like this.
this is my code of how to get one of the entities, like name1 object:
public class Class1 {
private RestTemplate restTemplate;
private String url = "https://url.com/api";
private Response response;
private Market market ;
public class1(){
restTemplate = new RestTemplate();
response = restTemplate.getForObject(url,Response.class);
}
#Override
public Market getResults() {
market = response.getResult();
System.out.println(Market);
return null;
}
}
and the response class is like so :
#JsonIgnoreProperties(ignoreUnknown = true)
#Getter
#Setter
#NoArgsConstructor
public class Response {
#JsonProperty("name1")
private Market result;
}
how can i get all those elements as an array or ArrayList?
this API is from 3rd party website and there's many entities liek that in the Json response.
thanks in advance.
So in the Json above, it is not an array but a list of key value pair.
This is what an array looks like in Json:
{
marketResults: [
{
id:2,
price:12,
name:"Bob:
},
{
id:111,
price:1.1,
name:"Ron:
},
{
id:10,
price:33,
name:"jhon:
}
]
}
Then what you could have done is:
public class Response {
private List<Market> marketResults;
}
But since your example is a map, you need to to use a MAP
public class Response {
private Map<String, Object > marketResults;
}
That post actually similar to yours: Reading JSON map structure via spring boot
If you can use Gson library that has native support for this use-case.
Keeps your code clean and typed.
#Getter
#Setter
public class Response {
#SerializedName(value = "name1", alternate={"name2","name3"})
private Market result;
}
#SerializedName is the #JsonProperty equivalent in Gson.

How to accept JSON POST parameters as #RequestParam in Spring Servlet?

I'm trying to create a POST servlet that should be called with JSON request. The following should work, but does not. What might be missing?
#RestController
public class MyServlet {
#PostMapping("/")
public String test(#RequestParam String name, #RequestParam String[] params) {
return "name was: " + name;
}
}
JSON POST:
{
"name": "test",
"params": [
"first", "snd"
]
}
Result: name is always null. Why?
"Response could not be created: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present"
In general I don't pass a request param in a POST method. Instead, I am using a DTO to pass it in the body like:
#RequestMapping(value = "/items", method = RequestMethod.POST)
public void addItem(#RequestBody ItemDTO itemDTO)
Then, you need to create the ItemDTO as a POJO with the necessary fields.
In addition to #stzoannos answer, if you do not want to create POJO for json object, you can use google GSON library to parse json into JsonObject class, which allow to work with parameters through same as get and set methods.
JsonObject jsonObj = new JsonParser().parse(json).getAsJsonObject();
return "name is: " + jsonObj.get("name").getAsString();

Custom json in Spring

I have configured in an Spring 3 application a ContentNegotiatingViewResolver so when I invoke a controller with a URL which looks like **.json it returns a json object using jackson library.
If I call this method:
#RequestMapping("/myURL.json")
public List<MyClass> myMethod(){
List<MyClass> mylist = myService.getList();
return mylist;
}
In the JSON I receive I have:
{"myClassList":[
{ object 1 in json },
{ object 2 in json },
{ object 3 in json } ...
]
}
my questions are: ¿is there any way to configure the name myClassList which is used in the json? ¿is it possible in this way a json without this variable (something like the following one)?
[
{ object 1 in json },
{ object 2 in json },
{ object 3 in json } ...
]
Thanks.
You can return a org.springframework.web.servlet.ModelAndView object, instead of a List object directly. On the modelAndView object you can set the name of the key. Please refer to the following snippet:
#RequestMapping("/myURL.json")
public ModelAndView myMethod(){
ModelAndView modelAndView = new ModelAndView();
List<MyClass> mylist = myService.getList();
modelAndView.addObject("MyClassName", myList);
return modelAndView;
}

Categories