Splitting a nested json to smaller jsons using Gson - java

I want to get a part of list json from a whole nested one. I have a json that looks like following:
{
"response": 200,
"responseMsg": "Allright",
"location": [
{
"stateId": 1,
"stateName": "West Bengal",
"district": [
{
"districtId": 15,
"districtName": "abc",
"village": [
{
"villageId": 121,
"villageName": "ABC"
},
{
"villageId": 90,
"villageName": "XYZ"
}
]
},
{
"districtId": 11,
"districtName": "xyz",
"village": [
{
"villageId": 58,
"villageName": "PQR"
}
]
}
]
}
]
}
I have written the bean files as following :
Details.java:
public class Details {
private int response = 0;
private String responseMsg = null;
private List<State> states = null;
public List<State> getLocation() {
return location;
}
State.java:
public class State {
private int stateId = 0;
private String stateName=null;
private List<District> district;
public List<District> getDistrict() {
return district;
}
Now, I want only the State json differently so that I can then use use it as List to populate the spinner in android.
For parsing the json, I am using
Gson googleJson = builder.create();Details details = googleJson.fromJson(result, Details.class);
List<State> stateList = details.getLocation();
But when i again convert this to json using gson.toJson(stateList) this gives:
[
{
"district": [
{
"village": [
{
"villageName": "Mekhliganj",
"villageId": 57
}
],
"districtName": "Cooch Bihar",
"districtId": 10
}
],"stateName=West Bengal","stateId":1
}
}
But this is other way round as state name goes in end when i again convert it to json.
Also , this same json (stateList) gives null pointer exception when I again try to parse it as:
State stateObj = gson.fromJson(stateList,State.class);
What should be the correct way to do this ? i.e. get a part of json (list) from a whole using gson and parse that part ?

Got the solution for you...
You are not passing the whole response in below function
try this steps to get whole response :
1) Store the data in String or any object class you are storing.
2)
Gson gson = new Gson();
String string = gson.toJson(response);
Note : You are just parsing remaining response. You are not parsing the original response. Just recheck the response when you parse in above function by putting break point on it.

public class Details {
private int response = 0;
private String responseMsg = null;
private Location location = null;
//add getter and setter
}
public class Location{
private List<State>stateList;
//add getter and setter
}
Finally
public class State {
private int stateId = 0;
private String stateName=null;
private List<District> district;
//add getter and setter
}

Related

I want to extract a value from a json

I want to extract a key and its value from json object. I am having a 3 objects in a json with parent child relation, named as
1. Parent,
2. childOne_OfParent and
3. child_OF_childOne.
I want to extract all the value of "userQueryId" from child_OF_childOne and store into a string type variable.
How do I perform this. Thanks in advance.
My Json object is:
{
"createdBy": "****",
"dashboardId": 1,
"childOne_OfParent": [
{
"createdBy": null,
"dashboardSectionId": 1,
"child_OF_childOne": [
{
"createdBy": "XYZ",
"userQueryId": "283"
},
{
"createdBy": "ABC",
"userQueryId": "284"
},
{
"createdBy": "AWS",
"userQueryId": "285"
}
]
}
]
}
You can use the json to create a model java class like this. I used your json to create the class using the site https://codebeautify.org/json-to-java-converter. You can give a classname of your choice in the Class_Name.
public class Class_Name {
private String createdBy;
private float dashboardId;
ArrayList < Object > childOne_OfParent = new ArrayList < Object > ();
// Getter Methods
public String getCreatedBy() {
return createdBy;
}
public float getDashboardId() {
return dashboardId;
}
// Setter Methods
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public void setDashboardId(float dashboardId) {
this.dashboardId = dashboardId;
}
}
Then you can use the Jackson to convert your json into a java object and access the data you want. Here jsonString is your json and the objResp is your object.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Class_Name objResp = mapper.readerFor(Class_Name.class).readValue(jsonString);
Here is a useful guide for that. https://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
The tool for these kind of tasks is JsonPath. It has xpath-like search capabilities.
Here is a working example of the given question
public static void main(String[] args) {
String searchQueryIds = "$.childOne_OfParent[*].child_OF_childOne[*].userQueryId";
try (InputStream is = Files.newInputStream(Paths.get("c:/temp/test.json"))) {
List<String> ids = JsonPath.parse(is).read(searchQueryIds);
System.out.println(ids);
} catch (Exception e) {
e.printStackTrace();
}
}
Assuming there is pojo for json and jackson library available. It will return comma separated queryUserIds.
Parent parent = new ObjectMapper().reader(Parent.class).readValue(inputJson);
String userIds = parent.getChildOne_OfParent().get(0).getChild_OF_childOne().stream()
.map(c -> c.getuserQueryId())
.collect(Collectors.joining(","));

Json Request with POSTMAN

I have this class:
#Getter
#Setter
IntestatarioPrivacySospensiva {
private IntestatarioInput intestatario;
private List<DatiPrivacySospensiva> datiPrivacy;
private String sportelloRiferimento;
private String riferimento;
private String note;
private String accettazioneConsensoC1;
private String accettazioneConsensoC3;
}
I have to make a JSON request to map this object, I have made this but it is never seen as IntestatarioPrivacySospensiva object.
[
{
//this are intestatarioInput variable
"abi":"abi",
"cf":"cf",
"ndg":"ndg"
},
{//This are datiprivacy variable
"tipoConsenso":"tipoConsenso",
"consenso":"consenso"
},
{
"sportelloRiferimento":"sportelloRif",
"riferimento":"riferimento",
"note":"note",
"accettazioneConsensoC1":"true",
"accettazioneConsensoC3":"false"
}
]
My service have in the request ArrayList x; how i have to map it in json?
I'm using Postman to send JSON.
I believe this should work:
[{
"sportelloRiferimento":"sportelloRif",
"riferimento":"riferimento",
"note":"note",
"accettazioneConsensoC1":"true",
"accettazioneConsensoC3":"false",
"intestatario" : {
"abi":"abi",
"cf":"cf",
"ndg":"ndg"
},
"datiPrivacy" : [ {
"tipoConsenso":"tipoConsenso",
"consenso":"consenso"
} ]
},
{
"sportelloRiferimento":"sportelloRif",
"riferimento":"riferimento",
"note":"note",
"accettazioneConsensoC1":"true",
"accettazioneConsensoC3":"false",
"intestatario" : {
"abi":"abi",
"cf":"cf",
"ndg":"ndg"
},
"datiPrivacy" : [ {
"tipoConsenso":"tipoConsenso",
"consenso":"consenso"
} ]
}]
You can use Jackson 2.x to get JSON strings from your Java objects. Checkout the below example:
https://www.mkyong.com/java/jackson-2-convert-java-object-to-from-json/

How to Parse Nested / Multiple Json Objects using Retrofit

The JSON I'm parsing looks like this:
{ "version": 1
"data": {
"1001": {
"id": 1001,
"name": "herp",
"into": [
"3111": "we"
]
},
"1032": {
"id": 1002,
"name": "derp",
"into": [
"36": "w",
"12341: "c"
],
"tags": [
"hi there"
],
"cost" {
"even": 15
}
},
"1603": {
"id": 1003,
"name": "her",
"into": [
"37": "dll",
"58": "eow",
"32145": "3a"
],
"cost" {
"highest": 325
"lowest": 100
}
},
.... Even more data
}
The Json that is within "data" goes on for a while and does not have a set endpoint. I have no control over the Json, I'm just trying to read it. Unfortunately, with my class code I'm unable to get it to work. When I make a retrofit call the information inside "data" is empty.
I've tried many iterations of implementing this, including using a deserializer and restructuring my POJO code. This is the current state of my Data class:
public class Data {
private Map<String, Item> itemData;
// Relevant Getters, Setters and Constructors //
}
For my Item Class, the main issue is that the JSON Content isn't set, it can vary at times. As you can see above the values inside "into" vary and sometimes the amount of things within item changes as well such as "tags" or "cost":
public class Item {
private int id;
private String name;
private String group;
private String description;
private Map<String, String> into;
private List<String> tags;
private Map<String, Integer> cost;
// Relevant Getters, Setters and Constructors //
When I use this code my data class is empty, I don't see any errors in the log so I can't seem to figure out why the GSON isn't working with this.
In case you wanted to see how I construct my RestClient, here it is:
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(ROOT)
.setClient(new OkClient(new OkHttpClient()))
.setLogLevel(RestAdapter.LogLevel.FULL);
RestAdapter restAdapter = builder.build();
REST_CLIENT = restAdapter.create(DataApi.class);
I know that my Rest Query works because I can get the content within "version" but everything inside data is null.
I am officially a dumb scrub and completely looked over the easiest possible fix and should have my account and developer title revoked.
This is all I should have done:
public class ItemGroup {
private String version;
private Map<String,Item> data;
//...Man i'm so dumb...
}
AS REFERENCE FOR THE FUTURE. The reason why this works is because the JSON is in this format { { } { } { } }. Which means you have 3 objects of objects, as opposed to { [ ] [ ] [ ] } which is 3 objects of a list. What I had done was treat { { } { } { } } as { { { } { } { } } }. Which is not correct. By using a map which is basically a collection of pairs, we are able to imitate the { { } { } { } } with a Map.
Map Object { {Key-Pair Object} {Key-Pair Object} {Key-Pair Object} }
Just a quick idea for your Pojos:
Not sure if this will work. Maybe write a custom deserializer.
public class YourResponse {
int version;
Data data;
class Data {
Subdata subData;
}
class Subdata {
private int id;
private String name;
private ArrayList<Into> into;
private ArrayList<String> tags;
//...
}
class Into {
// "3111": "we"
private String into;
}
}

How to deserialize an array of objects using Jackson or any other api?

I have a model defined to which i need to map the jsonArray.The model is as follows:
#JsonPropertyOrder({
"Command",
"Created",
"Id",
"Image",
"Labels",
"Names",
"Ports",
"Status"
})
public class Container {
#JsonProperty("Command")
private String Command;
#JsonProperty("Created")
private long Created;
#JsonProperty("Id")
private String Id;
#JsonProperty("Image")
private String Image;
#JsonProperty("Labels")
private List<String> Labels;
#JsonProperty("Names")
private List<String> Names = new ArrayList<String>();
#JsonProperty("Ports")
private List<Port> Ports = new ArrayList<Port>();
#JsonProperty("Status")
private String Status;
//Getters and Setters
}
The response is JSONArray and this is what i have to map to the Container Class which is as follows:
[
{
"Command":"/usr/sbin/sshd -D",
"Created":1429686533,
"Id":"c00afc1ae5787282fd92b3dde748d203a83308d18aaa566741bef7624798af10",
"Image":"jay8798:latest",
"Labels":{
},
"Names":[
"/jay8798"
],
"Ports":[
{
"IP":"0.0.0.0",
"PrivatePort":22,
"PublicPort":32845,
"Type":"tcp"
},
{
"IP":"0.0.0.0",
"PrivatePort":3306,
"PublicPort":32846,
"Type":"tcp"
}
],
"Status":"Up 12 hours"
},
{
"Command":"/usr/sbin/sshd -D",
"Created":1429686039,
"Id":"d70f439231d99889c1a8e96148f13a77cb9b83ecf8c9d4c691ddefa40286c04c",
"Image":"jay898:latest",
"Labels":{
},
"Names":[
"/jay898"
],
"Ports":[
{
"IP":"0.0.0.0",
"PrivatePort":22,
"PublicPort":32841,
"Type":"tcp"
},
{
"IP":"0.0.0.0",
"PrivatePort":3306,
"PublicPort":32842,
"Type":"tcp"
}
],
"Status":"Up 12 hours"
}
]
This is what I have tried but nothing seems to be working:
Container[] containerList = mapper.readValue(containerResponse, Container[].class);
int totalContainers = containerList.length;
//This will return correct length of the container.
System.out.println("This is the retrived size : " + containerList.length);
for(Container cont : containerList) {
// this statement will print 'null'.There is no exception thrown at this point.
System.out.println("Container Id : "+cont.getId());
}
Or
List<Container> containerList =
mapper.readValue(containerResponse, new TypeReference<List<MyClass>>(){});
I followed Jackson Deserialize and tried all the solutions mentioned in the post.
It is not able to map to the model.All the fields are null one it reads the values. No value is mapped to the attribute of Container class.Any thing missing in the model or do i need to write a customer logic to deserialize the json ?
First off, I'm assuming that
"Labels": {
},
should actually be
"Labels": [
],
since you've defined it to be a list of Strings and not an object of it's own.
This code works for me:
Port.java:
public class Port {
#JsonProperty("IP")
private String ip;
#JsonProperty("PrivatePort")
private int privatePort;
#JsonProperty("PublicPort")
private int publicPort;
#JsonProperty("Type")
private String type;
// Getters and setters
}
main():
String json = ... // Your JSON with the above correction
ObjectMapper objectMapper = new ObjectMapper();
List<Container> containers = objectMapper.readValue(json, new TypeReference<List<Container>>() {});
System.out.println(containers.size());
for(Container container : containers) {
System.out.println("Container Id : " + container.getId());
}
2
Container Id : c00afc1ae5787282fd92b3dde748d203a83308d18aaa566741bef7624798af10
Container Id : d70f439231d99889c1a8e96148f13a77cb9b83ecf8c9d4c691ddefa40286c04c
I'm surprised you are not getting an exception when trying to deserialize the object. When I run your code locally I get a
Exception in thread "main"
com.fasterxml.jackson.databind.JsonMappingException: Can not
deserialize instance of java.util.ArrayList out of START_OBJECT token
The reason looking like you are trying to serialize into an Array when it is a JSON object.
"Labels":{
},
That is a JSON object, so you should change your type to reflect what it is, or change the serialization of that JSON property to be an array. If you just want to change the type in your Container class, you should use a Map:
#JsonProperty("Labels")
private Map<String, Object> Labels;

How to convert Json String with dynamic fields to Object?

I have the followed snipets of Json String:
{
"networks": {
"tech11": {
"id": "1",
"name": "IDEN"
},
"tech12": {
"id": "2",
"name": "EVDO_B"
}
}
}
I use some methods to convert this String to Object:
private static Gson mGson = new Gson();
...
public static WebObjectResponse convertJsonToObject(String jsonString) {
WebObjectResponse webObjectResponse = null;
if(jsonString != null && jsonString.length() > 1){
webObjectResponse = mGson.fromJson(jsonString, WebObjectResponse.class);
}
return webObjectResponse;
}
Where WebObjectResponse is class that should represent above mentioned String.
Its not complicated if I get static fields.
But in my case the values have different names: tech11, tech12 ....
I can use #SerializedName but its works in specific cases like convert "class" to "class_".
As you see networks Object defined as list of tech Objects but with different post-fix.
public class WebObjectResponse{
private DataInfoList networks = null;
}
This is static implementation, i defined 2 values tech11 and tech12 but next response might be techXX
public class DataInfoList {
private DataInfo tech11 = null;
private DataInfo tech12 = null;
}
public class DataInfo {
private String id = null;
private String name = null;
}
What is the good way to convert current Json String to Object where list of elements are Objects too and have different names?
Thank you.
Use a Map!
I would do the following
public class WebObjectResponse {
private Map<String, DataInfo> networks;
}
public class DataInfo {
private String id = null;
private String name = null;
}
// later
Gson gson = new Gson();
String json = "{\"networks\": {\"tech11\": { \"id\": \"1\",\"name\": \"IDEN\" }, \"tech12\": { \"id\": \"2\", \"name\": \"EVDO_B\" } }}";
WebObjectResponse response = gson.fromJson(json, WebObjectResponse .class);
For each object in json networks, a new entry will be added to the Map field of your class WebObjectResponse. You then reference them by techXX or iterate through the keyset.
Assuming a structure like this
{
"networks": {
"tech11": {
"id": "1",
"name": "IDEN"
},
"tech12": {
"id": "2",
"name": "EVDO_B"
},
"tech13": {
"id": "3",
"name": "WOHOO"
}, ...
}
}
We would need your class structure for more details.
As far as I am aware, I think you will need to have some mappings defined somewhere (I used xml's) and then try to match json with one of the mappings to create objects.
Google gson is good. I did it in Jackson
Also, converting objects should be trivial. But since you might have variable fields like tech11 and tech12 , you might want to store the "network" value as a string and then extract fields out of it when required.
Hope I could help.
Edit : Sotirious nails it.
Please use this link for converting SON Response to Java POJO class
http://www.jsonschema2pojo.org/

Categories

Resources