Converting JSON Array to Java Array always throws empty values - java

So I have this variable specCifDetailsReturn which contains the ff. payload
[
{"ax21:cHType":"S",
"ax21:cardNumber":4***********7126,"ax21:returnCde":"00",
"ax21:cancelCode":"",
"ax21:vipCode":"",
"ax21:custrNbr":"0*****3426"},
{"ax21:cHType":"S",
"ax21:cardNumber":4***********3038,"ax21:returnCde":"00",
"ax21:cancelCode":"H",
"ax21:vipCode":"",
"ax21:custrNbr":"0*****3426"}
]
And the ff. Model Class to extract the params I need from the Array
#Data
#AllArgsConstructor
#NoArgsConstructor
#JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public final class SpecCifInfo {
#JsonAlias("ax21:cHType")
private String cHType;
#JsonAlias("ax21:cardNumber")
private String cardNumber;
}
I am trying to convert it to a Java ArrayList so that I could loop into it and find a card number. But for some reason it always throws a null value on the log even though the specCifDetailsReturn variable has a value. Below is the snippet of my code.
Gson gson = new Gson();
Type type = new TypeToken<List<SpecCifInfo>>(){}.getType();
ArrayList<SpecCifInfo> specDetails = gson.fromJson(specCifDetailsReturn.toString(),type);
for (SpecCifInfo specInfo : specDetails){
LOGGER.debug("Spec CIF Details", specInfo.getCHType() + "-" + specInfo.getCardNumber());
}
Sample Output of the SpecCifInfo Object that has null values

Those annotations are for the Jackson library, and you are manually using Gson. You should either keep them and just let Spring handle the deserialization for you by specifying a List<SpecCifInfo> parameter in the controller method, or you should use GSON's #SerializedName annotation. Either way will work.

Related

Will Gson set a field to null when JSON doesn't contain it?

I actually have multiple questions regarding Gson.
The first one being if Gson would set the value of a field to null when the provided JSON does not contain any field matching it.
For example, when the provided JSON features the field name but the class I deserialize it to contains name and avatar, would avatar be null?
The next question is in relation to the above one. When I would set a field with an already predefined value, would Gson override it, even if it isn't provided in the JSON (overrides it to null) or would it simply ignore the field and move on?
And finally would I want to know if Gson would still set a value to name when I would use #SerializedName("username") but the JSON contains name.
I want to update my API, including some bad namings of JSON fields, but I want to make the transition of it for the people using it a smooth as possible, so I want to still (temporary) provide the old field name, while also providing support for the new one. Is that possible using the #SerializedName annotation?
I'm still a beginner with Gson and the Gson User Guide wasn't that helpful for me to answer those two specific questions (Or I overlooked it which would also be possible).
I tried implementing this. Here is my code. I hope the output at the end answers your question.
JSON used:
{
"name": "Robert",
"weather": "19 deg"
}
Main class:
public class GSONExample2 {
private static final String jsonStr = "JSON Mentioned above";
public static void main(String[] args) {
GsonDataExample root = new Gson().fromJson(jsonStr, GsonDataExample.class);
System.out.println(root);
}
}
POJO:
class GsonDataExample {
#SerializedName("username")
private String name;
private String avatar;
#SerializedName(value="weather", alternate = "temperature")
private String weather;
private String nameWithDefault = "Default name";
// getters, setters and toString() implemented
}
Output:
GsonDataExample(name=null, avatar=null, weather=19 deg, nameWithDefault=Default name)
To map multiple keys to same attributes, you can use #SerializedName(value="weather", alternate = "temperature") as shown above.

Gson cannot de-json-lize what it json-lized?

public static String toJsonString(Object obj) {
Gson gson = new Gson();
return gson.toJson(obj);
}
Using this method to json-lize the object and then use this to de-json-lize
Gson gson = new Gson();
gson.fromJson(this.getThreadDumpVoJson(), ThreadDumpVo.class);
Everything works fine until I just added a new field to this ThreadDumpVo
Map<StackStatePair, Integer> traceStatePairSortedSizeGroup;
then Exception thrown as follows:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1540 path $.traceStatePairSortedSizeGroup.
The StackStatePair is defined as follows:
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class StackStatePair {
String callStack;
String state;
}
Previously I was trying to use import javafx.util.Pair; but it prompts the same issue, what's going on here?
I cannot use composite key?
"traceStatePairSortedSizeGroup": {
"StackStatePair(callStack\u003dDeadLoopThread.lambda$createBusyThread$0(DeadLoopThread.java:7)|DeadLoopThread$$Lambda$1/2080166188.run(Unknown Source)|java.lang.Thread.run(Thread.java:748), state\u003dRUNNABLE)": 1,
"StackStatePair(callStack\u003djava.lang.Object.wait(Native Method)|java.lang.Object.wait(Object.java:502)|java.lang.ref.Reference.tryHandlePending(Reference.java:191)|java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153), state\u003dWAITING)": 1,
"StackStatePair(callStack\u003djava.lang.Object.wait(Native Method)|java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)|java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)|java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209), state\u003dWAITING)": 1
}
No, you cannot use such composite key if you are parsing the JSON using Gson. The key itself is not a JSON String, which makes it not parse-able using Gson. It can only be parsed as a String.
This is not an array inside the traceStatePairSortedSizeGroup. If it was an array, then we could have stored the strings into a String array and then we could have parsed the values from the array. That's why you have the JsonSyntaxException.
If there is any chance to get your JSON body modified, then I would like to suggest you change it to keep it simple.

How can I deserialize JSON to an object with a HashMap attribute?

Right now I am using Gson to deserialize JSON to Object.
The JSON looks like this:
[
{
"hash":"c8b2ce0aacede58da5d2b82225efb3b7",
"instanceid":"aa49882f-4534-4add-998c-09af078595d1",
"text":"{\"C_FirstName\":\"\",\"ContactID\":\"2776967\",\"C_LastName\":\"\"}",
"queueDate":"2016-06-28T01:03:36"
}
]
And my entity object looks like this:
public class AppCldFrmContact {
public String hash;
public String instanceid;
public HashMap<String,String> text;
public String queueDate;
}
If text was a String data type, everything would be fine. But then I wouldn't be able to access different fields as I want to.
Is there a way to convert given JSON to Object I want?
The error I am getting is: Expected BEGIN_OBJECT but was STRING at line 1 column 174, which is understandable if it cannot parse it.
The code doing the parsing:
Type listType = new TypeToken<List<AppCldFrmContact>>() {
}.getType();
List<AppCldFrmContact> contacts = gson.fromJson(response.body, listType);
For you expected result, JSON data should be like below format,
[
{
"hash":"c8b2ce0aacede58da5d2b82225efb3b7",
"instanceid":"aa49882f-4534-4add-998c-09af078595d1",
"text":{"C_FirstName":"","ContactID":"2776967","C_LastName":""},
"queueDate":"2016-06-28T01:03:36"
}
]
You are getting this error because text field is a JSON map serialized to the string. If it is an actual your data and not a just an example, you can annotate a field with #JsonDeserialize and write your own custom JsonDeserializer<HashMap<String,String>> which will make deserialization 2 times.

Can not deserialize instance with jackson

I'm working on a RESTful app in which the response is passed as JSON string from Extjs to the java , so I am using the jackson to deserialize into the java POJO.
Below is my request:
{
"filter": "[{"type":"string","value":"sdadsadsa","field":"groupName"}]",
"limit": 10
}
The FilterParams class looks like this:
class FilterParams {
#JsonProperty( value = "type" )
private String type;
/** The value. */
#JsonProperty( value = "value" )
private String value;
/** The group name. */
#JsonProperty( value = "field" )
private String field;
}
For conversion to pojo am using below code
mapper.readValue(json, FilterParams.Class);
But still am getting the "Can not deserialize instance of FilterParams" . How to convert it into the pojo.
Any help would be greatly appreciated. Thanks.
Your JSON is invalid. Value of filter shouldn't start with " if it's a JSON array, or should have escaped inner " if it's a String.
Your FilterParams class does not reflect the data in your JSON at all: it should have a limit int property and an array or a Collection of Filters
Then you should have a Filter class with type, value and field properties
Your JSON contains 2 elements : filter & limits so that Jackson is not able to match this JSON String into a FilterParams object.
To ignore the JSON part that deal with limit, do the following :
JsonNode tree = mapper.readTree(<JSON_STRING>);
FilterParams fp = mapper.treeToValue(tree.get("filter"), FilterParams.class);

Map generic JSON object to Map interface with GSON

Given the following JSON object
{
"id": 5,
"data: { ... }
}
Is it possible to map this to the following POJO?
class MyEntity {
int id;
Map<String, Object> data;
}
Because I would like to leave the data object open ended. Is this even possible or what is a better approach to go about this? I am doing this on Android.
I don't have any idea about Android application but you can achieve it using Gson library easily.
The JSON that is used in your post is not valid. It might be a typo. Please validate it here on JSONLint - The JSON Validator
Simply use Gson#fromJson(String, Class) method to convert a JSON string into the object of passed class type.
Remember the name of instance member must be exactly same (case-sensitive) as defined in JSON string as well. Read more about JSON Field Naming
Use GsonBuilder#setPrettyPrinting() that configures Gson to output Json that fits in a page for pretty printing.
Sample code:
String json = "{\"id\": 5,\"data\": {}}";
MyEntity myEntity = new Gson().fromJson(json, MyEntity.class);
String prettyJsonString = new GsonBuilder().setPrettyPrinting().create().toJson(myEntity);
System.out.println(prettyJsonString);
output:
{
"id": 5,
"data": {}
}

Categories

Resources