I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?
Google Gson supports generics and nested beans. The [] in JSON represents an array and should map to a Java collection such as List or just a plain Java array. The {} in JSON represents an object and should map to a Java Map or just some JavaBean class.
You have a JSON object with several properties of which the groups property represents an array of nested objects of the very same type. This can be parsed with Gson the following way:
package com.stackoverflow.q1688099;
import java.util.List;
import com.google.gson.Gson;
public class Test {
public static void main(String... args) throws Exception {
String json =
"{"
+ "'title': 'Computing and Information systems',"
+ "'id' : 1,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Level one CIS',"
+ "'id' : 2,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Intro To Computing and Internet',"
+ "'id' : 3,"
+ "'children': 'false',"
+ "'groups':[]"
+ "}]"
+ "}]"
+ "}";
// Now do the magic.
Data data = new Gson().fromJson(json, Data.class);
// Show it.
System.out.println(data);
}
}
class Data {
private String title;
private Long id;
private Boolean children;
private List<Data> groups;
public String getTitle() { return title; }
public Long getId() { return id; }
public Boolean getChildren() { return children; }
public List<Data> getGroups() { return groups; }
public void setTitle(String title) { this.title = title; }
public void setId(Long id) { this.id = id; }
public void setChildren(Boolean children) { this.children = children; }
public void setGroups(List<Data> groups) { this.groups = groups; }
public String toString() {
return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
}
}
Fairly simple, isn't it? Just have a suitable JavaBean and call Gson#fromJson().
See also:
- Json.org - Introduction to JSON
- Gson User Guide - Introduction to Gson
I looked at Google's Gson as a potential JSON plugin. Can anyone offer some form of guidance as to how I can generate Java from this JSON string?
Google Gson supports generics and nested beans. The [] in JSON represents an array and should map to a Java collection such as List or just a plain Java array. The {} in JSON represents an object and should map to a Java Map or just some JavaBean class.
You have a JSON object with several properties of which the groups property represents an array of nested objects of the very same type. This can be parsed with Gson the following way:
package com.stackoverflow.q1688099;
import java.util.List;
import com.google.gson.Gson;
public class Test {
public static void main(String... args) throws Exception {
String json =
"{"
+ "'title': 'Computing and Information systems',"
+ "'id' : 1,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Level one CIS',"
+ "'id' : 2,"
+ "'children' : 'true',"
+ "'groups' : [{"
+ "'title' : 'Intro To Computing and Internet',"
+ "'id' : 3,"
+ "'children': 'false',"
+ "'groups':[]"
+ "}]"
+ "}]"
+ "}";
// Now do the magic.
Data data = new Gson().fromJson(json, Data.class);
// Show it.
System.out.println(data);
}
}
class Data {
private String title;
private Long id;
private Boolean children;
private List<Data> groups;
public String getTitle() { return title; }
public Long getId() { return id; }
public Boolean getChildren() { return children; }
public List<Data> getGroups() { return groups; }
public void setTitle(String title) { this.title = title; }
public void setId(Long id) { this.id = id; }
public void setChildren(Boolean children) { this.children = children; }
public void setGroups(List<Data> groups) { this.groups = groups; }
public String toString() {
return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
}
}
Fairly simple, isn't it? Just have a suitable JavaBean and call Gson#fromJson().
See also:
- Json.org - Introduction to JSON
- Gson User Guide - Introduction to Gson
Bewaaaaare of Gson! It's very cool, very great, but the second you want to do anything other than simple objects, you could easily need to start building your own serializers (which isn't that hard).
Also, if you have an array of Objects, and you deserialize some json into that array of Objects, the true types are LOST! The full objects won't even be copied! Use XStream.. Which, if using the jsondriver and setting the proper settings, will encode ugly types into the actual json, so that you don't loose anything. A small price to pay (ugly json) for true serialization.
Note that Jackson fixes these issues, and is faster than GSON.
Parse Dynamic JSON to Object in Java - Stack Overflow
java - How to convert Json String with dynamic fields to Object? - Stack Overflow
How do I transform a dynamic json to java class? - Stack Overflow
How to convert the following json string to java object? - Stack Overflow
Videos
You can use JSONObject from http://central.maven.org/maven2/org/json/json/20180813/json-20180813.jar
public static void main(String[] args) {
String input="{\r\n" +
" \"Sample_01\": {\r\n" +
" \"class\": \"Tenant\",\r\n" +
" \"A1\": {\r\n" +
" \"class\": \"Application\",\r\n" +
" \"template\": \"http\"\r\n" +
" }\r\n" +
" },\r\n" +
" \"Sample_02\": {\r\n" +
" \"class\": \"Tenant\",\r\n" +
" \"A2\": {\r\n" +
" \"class\": \"Application\",\r\n" +
" \"template\": \"http\"\r\n" +
" }\r\n" +
" }\r\n" +
"}";
JSONObject jsonObject = new JSONObject(input);
Set<String> keys =jsonObject.keySet();
for(String key:keys) {
System.out.println("Key :: "+key +", Value :: "+jsonObject.get(key));;
}
}
If you again wants to parse the value of Sample_01 or Sample_02 or Sample_XX Check the instance of jsonObject like if(jsonObject.get(key) instanceof JSONObject) and Reiterate the loop
Extending the answer added by @Deepak. Both approaches are feasible but I preferred Gson as I was already using it.
Using JSONObject
JSONObject jsonObject = new JSONObject(input);
Set<String> keys =jsonObject.keySet();
for(String key:keys) {
System.out.println("Key :: "+key +", Value :: "+jsonObject.get(key));;
}
Using Gson
public static void main(String[] args) {
String json = "{\"Sample_01\":{\"class\":\"Tenant\",\"A1\":{\"class\":\"Application\",\"template\":\"http\",\"serviceMain\":{\"class\":\"Service_HTTP\",\"virtualAddresses\":[\"10.0.1.10\"],\"pool\":\"web_poolddd\"},\"web_poolddd\":{\"class\":\"Pool\",\"monitors\":[\"http\"],\"members\":[{\"servicePort\":80,\"serverAddresses\":[\"192.0.13.10\",\"192.0.14.11\"]}]}}},\"Sample_20\":{\"class\":\"Tenant\",\"A1\":{\"class\":\"Application\",\"template\":\"http\",\"serviceMain\":{\"class\":\"Service_HTTP\",\"virtualAddresses\":[\"10.2.2.2\"],\"pool\":\"web_pool_data\"},\"web_pool_data\":{\"class\":\"Pool\",\"monitors\":[\"http\"],\"members\":[{\"servicePort\":80,\"serverAddresses\":[\"192.0.10.10\",\"192.0.10.11\"]}]}}}}";
Type listType = new TypeToken<Map<String, Object>>(){}.getType();
Gson gson = new Gson();
Map<String,Object> myList = gson.fromJson(json, listType);
JsonParser parser = new JsonParser();
for (Map.Entry<String,Object> m : myList.entrySet())
{
System.out.println("==============");
if(m.getValue() instanceof String){
// get String value
}else{ // if value is an Object
System.out.println("VIP Sec: Name: "+m.getKey());
Map<String,Object> myList1 = gson.fromJson(m.getValue().toString(), listType);
for (Map.Entry<String,Object> m1 : myList1.entrySet())
{
if(!( m1.getValue() instanceof String)){
Map<String,Object> myList2 = gson.fromJson(m1.getValue().toString(), listType);
for (Map.Entry<String,Object> m2 : myList2.entrySet())
{
if(!( m2.getValue() instanceof String)){
Map<String,Object> myList3 = gson.fromJson(m2.getValue().toString(), listType);
for (Map.Entry<String,Object> m3 : myList3.entrySet())
{
if(m3.getKey().equals("virtualAddresses")){
System.out.println("VIP Sec: IP Address: "+m3.getValue());
}
else if(m3.getKey().equals("pool")){
System.out.println("Pool Sec: Name: "+m3.getValue());
}else if(m3.getKey().equals("monitors")){
JsonArray monitors = parser.parse(m3.getValue().toString()).getAsJsonArray();
int count = 0;
while(count < monitors.size()){
String monitor = monitors.get(count).getAsString();
System.out.println("Monitor: "+monitor);
count++;
}
}else if(m3.getKey().equals("members")){
JsonArray members = parser.parse(m3.getValue().toString()).getAsJsonArray();
int count = 0;
while(count < members.size()){
// Parsing as Object to key values by key directly
JsonObject mem = members.get(count).getAsJsonObject();
String port = mem.get("servicePort").getAsString();
System.out.println("Port: "+port);
JsonElement ipAddrs = mem.get("serverAddresses");
if(ipAddrs.isJsonArray()){
JsonArray ips = ipAddrs.getAsJsonArray();
int c = 0;
while(c < ips.size()){
String ip = ips.get(c).getAsString();
System.out.println("IP: "+ip);
c++;
}
}
count++;
}
}
}
}
}
}
}
}
}
}
OUTPUT:
==============
VIP Sec: Name: Sample_01
VIP Sec: IP Address: [10.0.1.10]
Pool Sec: Name: web_poolddd
Monitor: http
Port: 80.0
IP: 192.0.13.10
IP: 192.0.14.11
==============
VIP Sec: Name: Sample_20
VIP Sec: IP Address: [10.2.2.2]
Pool Sec: Name: web_pool_data
Monitor: http
Port: 80.0
IP: 192.0.10.10
IP: 192.0.10.11
Read more about 2nd approach here
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.
Could you use Retrofit 2.0? https://square.github.io/retrofit/ It easy works with converting dynamic json to Java collections like List or Map. And so pojo class will be:
Class ServiceRequest {
public String name;
public String addr;
public HashMap<String, String> dataPair;
}
What about this approach:
Class dataPair {
private HashMap<String, String> dt= new HashMap<String, String>();
}
No need to go with GSON for this; Jackson can do either plain Maps/Lists:
ObjectMapper mapper = new ObjectMapper();
Map<String,Object> map = mapper.readValue(json, Map.class);
or more convenient JSON Tree:
JsonNode rootNode = mapper.readTree(json);
By the way, there is no reason why you could not actually create Java classes and do it (IMO) more conveniently:
public class Library {
@JsonProperty("libraryname")
public String name;
@JsonProperty("mymusic")
public List<Song> songs;
}
public class Song {
@JsonProperty("Artist Name") public String artistName;
@JsonProperty("Song Name") public String songName;
}
Library lib = mapper.readValue(jsonString, Library.class);
Check out Google's Gson: http://code.google.com/p/google-gson/
From their website:
Gson gson = new Gson(); // Or use new GsonBuilder().create();
MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
You would just need to make a MyType class (renamed, of course) with all the fields in the json string. It might get a little more complicated when you're doing the arrays, if you prefer to do all of the parsing manually (also pretty easy) check out http://www.json.org/ and download the Java source for the Json parser objects.
I want to convert the following text file into a java object list, HashMaps seem not complext enough as the text file is Json
info = [{"key":"1",
"request":"ok",
"group": "user"},{...},...{}]
Assume, your JSON payload looks like below:
{
"final_result": {
"result": {
"1597696140": 70.32,
"1597696141": 89.12,
"1597696150": 95.32
}
}
}
You can deserialise it to class:
@JsonRootName("final_result")
class ResultData {
private Map<Long, Double> result;
public Map<Long, Double> getResult() {
return result;
}
@Override
public String toString() {
return result.toString();
}
}
Like below:
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class Main {
public static void main(String[] args) throws IOException {
File jsonFile = new File("./src/main/resources/test.json");
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
ResultData resultData = mapper.readValue(jsonFile, ResultData.class);
System.out.println(resultData);
}
}
Above code prints:
{1597696140=70.32, 1597696141=89.12, 1597696150=95.32}
Converting the JSONObject to Map and setting the map to the pojo field, solved the issue and didn't lead me to writing a custom deserializer.
Map<Long, Double> resultData = objectMapper.readValue(resultData.getJSONObject("result").toString(), Map.class);
FinalResultData finaResultData = new FinalResultData(resultData);