I am unable to pull data from this in java. The problem is that how name_value_list will be fetched afterwards. Thanks in advance.
{
"id" : "ets7qkt1luugsj828jugs8vuq5",
"module_name" : "Users",
"name_value_list" : { "mobile_max_list_entries" : { "name" : "mobile_max_list_entries",
"value" : null
},
"mobile_max_subpanel_entries" : { "name" : "mobile_max_subpanel_entries",
"value" : null
},
"user_currency_id" : { "name" : "user_currency_id",
"value" : "-99"
},
.
.
"user_language" : { "name" : "user_language",
"value" : "en_us"
},
"user_name" : { "name" : "user_name",
"value" : "abcd"
},
"user_number_seperator" : { "name" : "user_number_seperator",
"value" : ","
}
}
}
I would say to try using google's Gson() to deserialize.
First, build the entity (or object mapping) classes, something like:
public class MobileMaxListEntry implements Serializable {
#Expose
#SerializedName("name")
private String name;
#Expose
#SerializedName("name")
private String value;
//getters / setters
}
Do this for each entity you have. Then:
public class ValuesList implements Serializable {
#Expose
#SerializedName("mobile_max_list_entries")
private MobileMaxListEntry mobile_max_list_entries;
#Expose
#SerializedName("mobile_max_subpanel_entries")
private MobileMaxSubpanelEntry mobile_max_subpanel_entries;
//getters/setters for everything
}
Then, the response class:
public class MyResponseClass implements Serializable {
#Expose
#SerializedName("id")
private String objectId;
#Expose
#SerializedName("module_name")
private String moduleName;
#Expose
#SerializedName("name_value_list")
private ValuesList valuesList;
//getters / setters for everything
}
Then, finally, in your code:
Gson gson = new Gson();
String json = "your_json_here";
MyResponseClass deserialized = gson.fromJson(json, MyResponseClass.class);
If you get an error, try adding default empty constructors for each class.
Simply extract the data in Map<String,Object> from JSON string.
GSON library
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> data = new Gson().fromJson(jsonString, type);
System.out.println(data.get("name_value_list"));
Jackson library
ObjectMapper mapper = new ObjectMapper();
TypeReference<Map<String, Object>> typeRef = new TypeReference<Map<String, Object>>() {};
Map<String, Object> data = mapper.readValue(reader, typeRef);
System.out.println(data.get("name_value_list"));
You can create a POJO class that is exact replica of the JSON string and can convert it in the Java object using GSON.
sample code:
class MobileDetail{
private NameValueList name_value_list;
private String module_name;
private String id;
}
class NameValueList{
private NameValue mobile_max_list_entries;
private NameValue mobile_max_subpanel_entries;
private NameValue user_currency_id;
private NameValue user_language;
private NameValue user_name;
private NameValue user_number_seperator;
}
class NameValue{
private String name;
private String value;
}
...
MobileDetail data =new Gson().fromJson(reader, MobileDetail.class);
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(data));
Related
I have a JSON structured like:
{
"id" : "123",
"name" : [ {
"id" : "234",
"stuff" : [ {
"id" : "345",
"name" : "Bob"
}, {
"id" : "456",
"name" : "Sally"
} ]
} ]
}
I want to map to the following data structure:
Class01
#Getter
public class Class01{
private String id;
#JsonDeserialize(using = Class01HashMapDeserialize.class)
private ArrayList<Class02> name;
}
Class02
#Getter
public class Class02{
private String id;
private ArrayList<Class03> stuff;
}
Class03
#Getter
public class Class03{
private String id;
private String name;
}
In my main Method im using an ObjectMapper with objectMapper.readValue(jsonString,new TypeReference<ArrayList<Class02>>(){}) to map this JSON to my Class01. This Class successfully deserealizes the Class02-array into the name array.
When it comes to the second array I don't know how to further deserialize as I am not able to access the json text from the class02 stuff entry.
#Override
public ArrayList<Class02> deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
ArrayList<Class02> ret = new ArrayList<Class02>();
ObjectCodec codec = parser.getCodec();
TreeNode classes02 = codec.readTree(parser);
if (classes02.isArray()) {
for (JsonNode class02 : (ArrayNode) classes02) {
if(classe02.get("stuff").isArray()){
ObjectMapper objectMapper = new ObjectMapper();
ArrayList<Class03> classes03 = objectMapper.readValue(class02.get("stuff").asText(), new TypeReference<ArrayList<Class03>>(){});
}
ret.add(new Class02(class02.get("id").asText(), classes03));
}
}
return ret;
}
Why did you put a #JsonDeserialize annotation ? Jackson shall be able to deserialize it just fine without any custom mapping:
#Getter
public class Class01{
private String id;
private ArrayList<Class02> name;
}
Also in a first pass, I would generate the getters/setters/constructor manually for the 3 classes. There may be issues with Lombok & Jackson that you may want to solve later once you made the first version of the code works (Can't make Jackson and Lombok work together)
And your reader shall be more like:
ObjectMapper objectMapper = new ObjectMapper();
String text = ... //Your JSon
Class01 class01 = objectMapper.readValue(text, Class01.class)
I have a class with such structure:
class SomeClass {
private String stringValue;
private Collection<String> collectionValue = new ArrayList<>();
private String jsonStringValue;
private boolean booleanValue;
}
And then I use
objectMapper.readValue(jsonString, SomeClass.class);
to parse this object from JSON.
The main problem is that jsonStringValue is a json inside of json:
{"stringValue" : "someString",
"collectionValue" : ["123456", "234567", "hello"],
"jsonStringValue" : "{
"someKey" : 1,
"anotherKey" : {
"againKey" : "value"
}
},
"booleanValue" : true
}
And trying to parse jsonStringValue it throws
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('a' (code 97)): was expecting comma to separate Object entries
Exactly "a" character from my example (json modified on security purposes)
I believe there should be some escaping rule for parsing json as a String.
How do I parse json value as a string?
First, your JSON string is not valid because there is a redundant double quote before the left bracket in jsonStringValue. The valid one looks like this:
{
"stringValue" : "someString",
"collectionValue" : ["123456", "234567", "hello"],
"jsonStringValue" : {
"someKey" : 1,
"anotherKey" : {
"againKey" : "value"
}
},
"booleanValue" : true
}
Second, jsonStringValue is not a simple String object, it is a nested JSON objects. Therefore, you are supposed to create corresponding classes for it as follows:
Class SomeClass {
private String stringValue;
private List<String> collectionValue = new ArrayList<>();
private JsonStringValue jsonStringValue;
private boolean booleanValue;
//general getters and setters
}
Class JsonStringValue {
private int someKey;
private AnotherKey anotherKey;
//general getters and setters
}
Class AnotherKey {
private String againKey;
//general getters and setters
}
At last, the given JSON string can be transformed into SomeClass POJO with ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
SomeClass someClass = mapper.readValue(jsonStr, SomeClass.class);
System.out.println(someClass.getjsonStringValue().getAnotherKey().getAgainKey());
Console output:
value
UPDATED
If you still want to transform the jsonStringValue object into String, an alternative way is shown as follows:
Create 2 classes - SomeClassOriginal and SomeClass, the only difference between them is the data type of jsonStringValue. The former one is JsonNode and later one is String.
Class SomeClassOriginal {
private String stringValue;
private List<String> collectionValue = new ArrayList<>();
private JsonNode jsonStringValue;
private boolean booleanValue;
//general getters and setters
}
Class SomeClass {
private String stringValue;
private List<String> collectionValue = new ArrayList<>();
private String jsonStringValue;
private boolean booleanValue;
public SomeClass(SomeClassOriginal someClassOriginal) {
super();
this.stringValue = someClassOriginal.stringValue;
this.collectionValue = someClassOriginal.collectionValue ;
this.jsonStringValue= someClassOriginal.jsonStringValue.toString();
this.booleanValue= someClassOriginal.booleanValue;
}
//general getters and setters
}
Then you can get the jsonStringValue as String like this:
ObjectMapper mapper = new ObjectMapper();
SomeClassOriginal someClassOriginal = mapper.readValue(jsonStr, SomeClassOriginal.class);
SomeClass someClass = new SomeClass(SomeClassOriginal);
System.out.println(someClass.getjsonStringValue());
Console output:
{"someKey":1,"anotherKey":{"againKey":"value"}}
I'm working on a personal project in Android and I want to use GSON to parse a JSON file containing the data I need.
I have a local JSON file with the following structure:
{
"Object1": {
"foo": "value1",
"bar": "value2",
"baz": "value3",
...
},
"Object2": {
"foo": "value4",
"bar": "value5",
"baz": "value6",
...
},
...
}
I have already made an Object class of the following structure:
Class Object {
String data;
...
}
How would I parse this JSON file with this structure?
EDIT: The JSON file I use is very large, it contains about 400+ of these objects of type Object. I would have to iterate over each object to create a new JSONObject, but I do not know how to do this.
In the solution below, we convert the JSON you've provided in your link as a JSONOject. Then we get the list of names contained in the JSON ("Abaddon", "Archeri", ...). Once we have the list we iterate through it. For each name we get the JSON object associated with it.
Then we use GSON to convert each object into a Demon object. The Demon class has been generated using http://www.jsonschema2pojo.org/ as suggested above.
As all the objects in the JSON have the same structure we need only one class to deserialize every single one of them.
Deserializer
public List<Demon> deserialize(String json) {
try {
JSONObject jsonObject = new JSONObject(json);
final JSONArray names = jsonObject.names();
final List<Demon> demons = new ArrayList<>();
final Gson gson = new Gson();
Demon demon;
for (int i = 0; i < names.length(); i++) {
demon = gson.fromJson(jsonObject.get(names.getString(i)).toString(), Demon.class);
demons.add(demon);
}
return demons;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
Demon class
public class Demon {
#SerializedName("ailments")
#Expose
public String ailments;
#SerializedName("align")
#Expose
public String align;
#SerializedName("code")
#Expose
public Integer code;
#SerializedName("inherits")
#Expose
public String inherits;
#SerializedName("lvl")
#Expose
public Integer lvl;
#SerializedName("pcoeff")
#Expose
public Integer pcoeff;
#SerializedName("race")
#Expose
public String race;
#SerializedName("resists")
#Expose
public String resists;
#SerializedName("skills")
#Expose
public List<String> skills = null;
#SerializedName("source")
#Expose
public List<String> source = null;
#SerializedName("stats")
#Expose
public List<Integer> stats = null;
public Demon(){
// Default constructor
}
}
Getting empty java object while populating the following type of Json.
a.json:
------
{
"queries": [{
"query": {
"id": "q1",
"description": "Fire query to get the Auth token !!"
}
}
],
"executeQuery": ["q2", "q3"]
}
Query.java :
-----------
Note : #Data will take care of creating setter getter by Lombok library.
#Data
public class Query {
#Expose #SerializedName("id")
String id;
#Expose #SerializedName("description")
String description;
}
GRT.java :
----------
#Data
public class GRT{
#Expose #SerializedName("queries")
List<Query> queries ;
#Expose #SerializedName("executeQuery")
List<String> executeQuery;
}
Client call :
----------------------------------------------
private void readJson() throws IOException{
String fileName = "a.json";
// Get Gson object
Gson gson = newGsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
// read JSON file data as String
String fileData = new String(Files.readAllBytes(Paths.get(fileName)));
// parse json string to object
GenericRestTestDefinition grtDef = gson.fromJson(fileData, GenericRestTestDefinition.class);
System.out.println(grtDef.toString());
}
Printing the following :
GRT(queries=[Query(id=null, description=null)], executeQuery=[q2, q3])
Dont know why GRT-> Query Object is not getting populated ????
The proper JSON for this would look like this..
{
"queries":
[
{"id":"q1","description":"Fire query to get the Auth token"},
{"id":"q2","description":"Fire query to get the Auth token 2"}
]
}
public class Test {
public static void main(String[] args) throws Exception {
readJson();
}
private static void readJson() throws IOException {
String json ="{\"queries\":[{\"id\":\"q1\",\"description\":\"Fire query to get the Auth token\"}]}";
// Get Gson object
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
GRT grt = new GRT();
grt.setQueries(Arrays.asList( new Query[]{new Query("q1", "Fire query to get the Auth token")} ));
System.out.println(gson.toJson(grt));
// parse json string to object
GRT grtDef = gson.fromJson(json, new TypeToken<GRT>(){}.getType());
System.out.println(grtDef.queries.get(0));
}
}
If you can't change the json file format you can use this pattern:
#Data
public class GRT{
#Expose #SerializedName("queries")
private List<QueryWrapper> queries = new ArrayList<>();
public List<Query> getQueries() {
return queries.stream().map(it->it.query).collect(Collectors.toList());
}
#Expose #SerializedName("executeQuery")
List<String> executeQuery = new ArrayList<>();
}
#Data
public class QueryWrapper {
#Expose #SerializedName("query")
Query query;
}
#Data
public class Query {
public
#Expose #SerializedName("id")
String id;
#Expose #SerializedName("description")
String description;
}
I am using GSON for the first time. I am trying to deserialise a JSON string into a custom object, but every property of my object is set to null. There are no parsing errors so I think the JSON properties are not mapping to the object?
Here is my code, if anyone could point out where I have gone wrong it would be much appreciated. I have checked everything against tutorial and cannot see the problem. The only thing is that there are more properties in the JSON string than in my object but I hope that does not matter.
JSON string:
{
"_id": "D7D4A7D8219CA25848257C63000A1B50",
"ReportingPerson": "TRAIN2 Ifap",
"InjuredPerson": "TRAIN3 Ifap",
"DateReported": {
"$date": "2014-01-17T00:00:00.000Z"
},
"Company": "test",
"Division": "Learning & Development",
"Site_id": "3CA9AD4E6066388648257B7500047D90",
"Department_id": "724BC4B509E7B61648257363002FD645",
"Area": "Training Room",
"DocNo": "002223",
"CreatedBy": "Ifap TRAIN2",
"DateComposed": {
"$date": "2014-01-17T01:50:23.000Z"
},
"OccurTime": "12:00:00",
"Affiliation": "Employee",
"BriefDescription": "Employee tripped over power lead in computer lab.",
"ThirdPartyInvolvedYN": "No",
"ThirdPartyName": "",
"ThirdPartyAddress": [
""
],
"ThirdPartyTel": "",
"Classification": "Minor Injury",
"Confidential": "",
"ConfidentialMonitors": [
""
],
"IncidentCategory": "2",
"IncidentCategoryPotential": "3",
"ReportableYN": "No",
"ExternalBody": [
""
],
"Authorisor": "",
"WorkSafeConfirmedYN": "No",
"Details": "Fell over cord in computer lab when walking through. Held hand out to brace fall and fell on pinkie finger.",
"Controls": [
"Tape over cord."
],
"Witnesses": [
"No"
],
"Supervisor": "TRAIN1 Ifap",
"IntAuthorisor": "TRAIN3 Ifap",
"IntAuthorisorNext": "",
"AssociatedRisks": {},
"OpenActions": {},
"ClosedActions": {}
}
POJO:
public class Incident {
#SerializedName("_id")
private String _id;
private String docNo;
private String site_id;
private String company;
private String division;
private String department_id;
private Date dateReported;
private String briefDescription;
private String thirdPartyInvolvedYN;
private String supervisor;
private String classification;
private String status;
private String injuredPerson;
private String reportingPerson;
private Date occurDate;
private String occurTime;
//Getters & Setters...
}
Main method:
public Incident convertJSONToBean(String json) {
Incident i = new Incident();
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
Type type = new TypeToken<Incident>(){}.getType();
try {
i = gson.fromJson(json, type);
} catch (JsonSyntaxException e) {
e.printStackTrace();
} catch (JsonIOException e) {
e.printStackTrace();
}
return i;
}
Type is set correctly to Incident.class. But any properties of the resulting Incident object are all null.
I tried commenting out all properties except _id to see if I could get just one to populate but it was still set to null.
In Json format DateComposed & DateReported properties are the Object, You need to create the
either custom model classes for them or write CustomDeserializer class for them.
"DateComposed": { "$date": "2014-01-17T01:50:23.000Z" }
"DateReported": {"$date": "2014-01-17T00:00:00.000Z"}
public class Incident {
#SerializedName("_id")
private String _id;
#SerializedName(value = "ReportingPerson")
// other properties, you need to put #SerializedName on each property
............
// No need to put SerializedName annotation on dateReported & dateComposed
private Date dateReported;
private Date dateComposed;
#SerializedName(value = "ThirdPartyAddress")
private List<String> thirdPartyAddress;
#SerializedName(value = "ConfidentialMonitors")
private List<String> confidentialMonitors;
#SerializedName(value = "ExternalBody")
private List<String> externalBody;
#SerializedName(value = "Controls")
private List<String> controls;
#SerializedName(value = "Witnesses")
private List<String> witnesses;
// getter/setter
....
}
Here is the CustomDeserializer class for Deserializing date properties
public class CustomDeserializer implements JsonDeserializer<Incident> {
#Override
public Incident deserialize(JsonElement json, Type type,
JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
final Gson gson = new Gson();
// Parse the JsonElement tree here
final Incident incident = gson.fromJson(json, Incident.class);
// getting date properties as string from JsonElement and parse them into date object.
String dateReportedStr = jsonObject.get("DateReported").getAsJsonObject().get("$date").getAsString();
String dateComposedStr = jsonObject.get("DateComposed").getAsJsonObject().get("$date").getAsString();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
try {
// setting date properties in incident object
incident.setDateReported(df.parse(dateReportedStr));
incident.setDateComposed(df.parse(dateComposedStr));
} catch (ParseException e) {
e.printStackTrace();
}
return incident;
}
}
Finally Parse it
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Incident.class, new CustomDeserializer());
Gson gson = gsonBuilder.create();
Incident incident = gson.fromJson(Your_JSON_STR, Incident.class);
You have interesting date objects in your json string. Such as;
"DateReported": {
"$date": "2014-01-17T00:00:00.000Z"
}
Which causes a JsonParseException because of your Incident class:
com.google.gson.JsonParseException: The date should be a string value
For your Incident class, Dates at json value should be something like;
"DateReported": "2014-01-17T00:00:00.000Z"
If you don't have an option to change dates at json value, then you should define its custom date holder class:
public class CustomDateHolder {
#SerializedName("$date")
private Date date;
// Getters & Setters...
}
And change those date fields' type to CustomDateHolder;
public class Incident {
#SerializedName("_id")
private String _id;
private String docNo;
private String site_id;
private String company;
private String division;
private String department_id;
private CustomDateHolder dateReported;
private String briefDescription;
private String thirdPartyInvolvedYN;
private String supervisor;
private String classification;
private String status;
private String injuredPerson;
private String reportingPerson;
private CustomDateHolder occurDate;
private String occurTime;
// Getters & Setters...
}
Also modify your GsonBuilder a little bit:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE);
gsonBuilder.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
Gson gson = gsonBuilder.create();