I am getting the following from a rest call.
[
{
"IMAGE": "",
"DESCRIPTION": "",
"HEADER": ""
}
]
I am using these values to construct another response to the calling client.
In that response, I want it to be in lower case as follows.
[
{
"image": "",
"description": "",
"header": ""
}
]
This is what I am doing currently to convert.
// a large json response received from the rest call.
Benefit benefits = // rest call
//this is above block of response where the keys are upper case currently.
benefits.get(FURTHER_DATA); // type is Object
// casting to my custom object.
List<FurtherData> data = (List<FurtherData>) benefits.get(FURTHER_DATA);
Works fine but the key is still upper case.
When I see it in debug format, I am expecting it to be a list of my FurtherData object.
Instead it is actually showing up as a LinkedHashMap. How? Am so confused. Please help. Thanks.
This is the custom FurtherData object. Another weird thing going on here. I can comment out all the fields here. Still works. Again... how?
#Getter
#Setter
public class FurtherData {
#JsonProperty("IMAGE")
private String image;
#JsonProperty("DESCRIPTION")
private String description;
#JsonProperty("HEADER")
private String header;
}
P.S: To note, this is not myself missing out some additional logic elsewhere.
>It's all happening in following line. If I comment it out, the response doesn't have the above block of data as expected.
List<FurtherData> data = (List<FurtherData>) benefits.get(FURTHER_DATA);
This is Benefit object.
// other fields
private List<FurtherInfo> furtherInfo;
Related
I'm on a Java Spring Boot project that makes API requests using RestTemplates.
Trying to implement pagination, makes the new JsonArray incoming has as first element an Integer and the rest are JsonElements.
Without pagination the value of the json incoming is:
[
{
"id":1234,
"name": null,
"...":...
},...
]
And these objects with their getter and setters correctly implented. p.d I don't need all the attributes of the incoming jsonelement.
public class WorkListBean extends WorkBean{
private List<WorkBean> lsWorkBean;
}
public class WorkBean implements Serializable {
private static final long serialVersionUID = -...L;
private long id;
private String name;
}
This returns WorkListBean[] to the client and works pretty well.
But with pagination implemented the incoming json is like this:
[
1,
{
"id":1234,
"name": null
},...
]
How could I extract this first Integer of the array?
I think maybe I could use a Deserializer with a Object Mapper to make a custom object that owns a Integer and a list or array of WorkBean. But I'm a little bit lost with this terms. Can anyone confirm am pointing in a good view?
Thanks in advance,
Grettings LaGallinaturuleta
That's a badly designed schema. Allthough it's technically allowed, putting elements of different types in the same array will make every client suffer.
If you can change the server side you're talking to, they should use a more user-friendly schema, like this:
{
"pageNumber":0,
"size":5,
"totalPages":4,
"content":[
{"studentId":"1","name":"Bryan","gender":"Male","age":20},
{"studentId":"2","name":"Ben","gender":"Male","age":22},
{"studentId":"3","name":"Lisa","gender":"Female","age":24},
{"studentId":"4","name":"Sarah","gender":"Female","age":26},
{"studentId":"5","name":"Jay","gender":"Male","age":20}
],
}
If not, you're going to need a custom deserializer indeed.
My web service (WS) receives an HTTP POST request and JacksonJsonProvider is deserializing incoming body object into JSON string. The DTO is simple:
public class SettingDTO {
private String key;
private String value;
...
}
The WS signature looks like this:
#Post
Response saveList(List<SettingDTO> list);
The WS is awaiting an array in the input. Example:
{
"settings": [
{
"key": "key1",
"value": "val1"
},
{
"key": "key2",
"value": "val2"
}
]
}
This results in an exception. Jackson does not know how to handle the leading "settings" label. If I try it without the label, just a plain array, it works well. But the requirement is set to use it the way it is.
One solution I know is to use a wrapper object, another DTO. I wonder if this could be solved without an extra wrapper? Maybe an annotation will do the job?
After deserialization, I want to end up with the populated List<Setting> settings ...
There are several ways can achieve this. But if you don't want to use an extra wrapper class, one way is to read the inner JSON string first, then deserialize it to List<SettingDTO> as follows:
Code snippet
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(jsonStr);
String settingsStr = root.get("settings").toString();
List<SettingDTO> settings = mapper.readValue(settingsStr, new TypeReference<List<SettingDTO>>(){});
System.out.println(settings.toString());
Console output
[SettingDTO [key=key1, value=val1], SettingDTO [key=key2, value=val2]]
BTW, if you have tried to add #JsonRootName(value = "settings") to class SettingDTO, AFAIK, it doesn't work for JSON array!
Problem: I have a request body where I have a predefined POJO class, inside this class I need to add another object as parameter. This new object at a given time may have random properties/attributes/params. How can I achieve this?
{
"id": "{{id}}",
"enableTouchId": true,
"idleLogoutMinutes": 10,
"platformSpecificPreferences": {
"ios": {
"terms": "1234",
"privacy": "12345"
},
"web": {
"terms" : "abc"
},
"android": {
"newProperty" : "newValue"
}
}
}
So the new object I am trying to add is platformSpecificPreferences, which when hit using rest calls might or might not have all the properties shown here, which is why I cannot use redefined POJO class for platformSpecificPreferences and create its object.
Solution I tried:
I thought of using JsonObject inside request body, which makes
#JsonProperty("platformSpecificPreferences")
private JsonObject platformSpecificPreferences;
but the problem is, I am not able to hit the api as it doesnt accept this parameter and gives 404.
Thanks in advance.
You can use, kind must a predefined pojo for platformSpecificPreferences but in the pojo you need to ignore values that are not given in the rest call!
You can do this with a json annotation:#JsonIgnoreProperties(ignoreUnknown = true) in the Pojo above the class.
I am trying to loop over the array of objects in java. I'm posting this value from client side to server side which is java.
"userList": [{
"id": "id1",
"name": "name1"
},
{
"id": "id2",
"name": "name2"
}]
Now I want to get the value of each id and name. I tried the code below:
for (Object temp : userList)
System.out.print(temp);
System.out.print(temp.getId());
}
But the output I get is:[object Object]
I'm sorry for this stupid question. But how will I get the value of id and name?
You're getting [object Object] because you didn't turn your JavaScript object into JSON on the client side before sending it to your server--you need to use something like JSON.stringify(object) in the browser.
Next, you will need to unpack your JSON into some sort of Java structure. The preferable way to do this is to let an existing tool such as Jackson or Gson map it onto a Java object that looks like:
class User {
String id;
String name;
}
How to do this will depend on your framework, but Spring MVC (for example) supports it mostly automatically.
Implement the toString method for your class according to how you want the printed output to look.
For example...
public class User {
private String id;
private String name;
// Constructors, field accessors/mutators, etc...
#Override
public String toString() {
return String.format("User {id: %s, name: %s}", this.id, this.name);
}
}
Your question does not have complete information. You certainly are skipping steps.
Before you start using the object in java you need to cast the object.
ArrayList<User> convertedUserList = (ArrayList<User>)userList;
for (User temp : convertedUserList)
System.out.print(temp);
System.out.print(temp.getId());
}
Let's take this example. I have a pojo class as below.
public class MyRecord{
private String name;
private String id;
//constructors and getters,setters
}
when I get the toJson(new MyRecord("MyName","myId") output for above I can get.
{
"name": "MyName",
"id": "123"
}
And I have inherited one as follows to add the dateTime.
public class MyRecordWithDateTime extends MyRecord{
private String DateTime;
//constructors and getters,setters
}
so when I called toJson(new MyRecordWithDateTime("2016-01-01", "MyName", "myId"))
The output is this
{
"name": "MyName",
"id": "123",
"dateTime": "2016-01-01"
}
but I actually need that as follows. (dateTime should come first.)
{
"dateTime": "2016-01-01",
"name": "MyName",
"id": "123"
}
Is there anyway to do that with keeping inheritance?
Maybe kinda late but just in case there is this annotation #JsonPropertyOrder
Field/member/attributes in a JSON collection do not have an order, and as far as this JSON data structure is concerned, the "order" doesn't matter.
The only reason I can imagine you are concerned with the order is for printing/presentation purposes. In that case I suggest you manually construct the JSON string yourself.
Before you put it in your JSON file, you can try to make an ordered List ( LinkedList, ArrayList or something like), then sort it as you want and after that put it in JSON.
But obviously, a better idea than mine exists!!
But the fact is: JSON doesn't need to be sorted! You just use the getter and it will find your value associated to the key! Even if it's in the last position.