I have following json which i need to convert into list of java objects.
{
"model":[
{
"syscall_1":"execve",
"syscall_2":"brk"
},
{
"syscall_1":"brk",
"syscall_2":"access"
},
{
"syscall_1":"access",
"syscall_2":"mmap"
},
{
"syscall_1":"mmap",
"syscall_2":"access"
}
]
}
I am using gson and its TypeToken>(){}.getType() API ,however I am bit confused about how my objects should look corresponding to input json.
How can I use TypeToken in this scenario?
Another option (not using the type token, but still achieves what you want) would be to parse the entire json object, then access the model array like so:
import com.google.gson.Gson;
import java.util.List;
public class TestMe {
public static void main(String[] args) {
String jsonSt2 = "{\"model\":[{\"syscall_1\":\"execve\",\"syscall_2\":\"brk\"},{\"syscall_1\":\"brk\",\"syscall_2\":\"access\"},{\"syscall_1\":\"access\",\"syscall_2\":\"mmap\"},{\"syscall_1\":\"mmap\",\"syscall_2\":\"access\"}]}";
System.out.println("your json: " + jsonSt2);
ModelObject object = new Gson().fromJson(jsonSt2, ModelObject.class);
System.out.println("Created Model object, array size is " + object.model.size());
for (ModelItem mi : object.model) {
System.out.println(mi.syscall_1 + " " + mi.syscall_2);
}
}
}
class ModelObject {
List<ModelItem> model;
}
class ModelItem {
String syscall_1;
String syscall_2;
}
Output
Created Model object, array size is 4
execve brk
brk access
access mmap
mmap access
mmap access
If you can use org.json to parse and construct list objects, you can try this.
String jsonSt2 = "{\"model\":[{\"syscall_1\":\"execve\",\"syscall_2\":\"brk\"},{\"syscall_1\":\"brk\",\"syscall_2\":\"access\"},{\"syscall_1\":\"access\",\"syscall_2\":\"mmap\"},{\"syscall_1\":\"mmap\",\"syscall_2\":\"access\"}]}";
List<Model> models = new ArrayList<>();
JSONObject jsonModelObject = new org.json.JSONObject(jsonSt2);
Object modelObject = jsonModelObject.get("model");
if (modelObject instanceof JSONArray) {
JSONArray itemsArray =(JSONArray) modelObject;
for (int index = 0; index < itemsArray.length(); index++) {
Model model = new Model();
JSONObject modelItereative = (JSONObject) itemsArray.get(index);
model.setSyscall_1(modelItereative.getString("syscall_1"));
model.setSyscall_2(modelItereative.getString("syscall_1"));
models.add(model);
}
}else if(modelObject instanceof JSONObject){
Model model = new Model();
JSONObject modelItereative = (JSONObject) modelObject;
model.setSyscall_1(modelItereative.getString("syscall_1"));
model.setSyscall_2(modelItereative.getString("syscall_1"));
models.add(model);
}
for(Model d22:models){
System.out.println(d22.getSyscall_1() + " " + d22.getSyscall_2());
}
Related
I'm trying to parse the below Json using the Gson lib in Java. When using other languages, such as C#, this JSON is parsed into an array, however it seems Gson converts this into a set of java attributes (which to be honest, makes more sense to me). Does anyone know if I can change this behaviour of the Gson lib?
{
"Outer": {
"0": {
"Attr1": 12345,
"Attr2": 67890
},
"1": {
"Attr1": 54321,
"Attr2": 09876
}
}
}
The below code demonstrates how Gson parses the array as a JsonObject. To be clear, I realise I've referenced outer as a JsonObject but I was just doing this to demonstrate the code. If I try and reference outer as an JsonArray, the code fails.
String json = "{\"Outer\": { \"0\": { \"Attr1\": 12345, \"Attr2\": 67890 }, \"1\": { \"Attr1\": 54321, \"Attr2\": 09876 }}}";
Gson gson = new GsonBuilder()
.disableHtmlEscaping()
.setLenient()
.serializeNulls()
.create();
JsonObject jo = gson.fromJson(json, JsonObject.class);
JsonObject outer = jo.getAsJsonObject("Outer");
System.out.println(outer);
System.out.println(outer.isJsonArray());
Result:
{"0":{"Attr1":12345,"Attr2":67890},"1":{"Attr1":54321,"Attr2":"09876"}}
false
//edit
I'm using this current simple Json as an example, however my application of this code will be to parse Json that's of varying and unknown shape. I therefore need Gson to automatically parse this to an array so that the isJsonArray returns true.
TL;DR: See "Using Deserializer" section at the bottom for parsing straight to array.
That JSON does not contain any arrays. An array would use the [...] JSON syntax.
Normally, a JSON object would map to a POJO, with the name in the name/value pairs mapping to a field of the POJO.
However, a JSON object can also be mapped to a Map, which is especially useful when the names are dynamic, since POJO fields are static.
Using Map
The JSON object with numeric values as names can be mapped to a Map<Integer, ?>, e.g. to parse that JSON to POJOs, do it like this:
class Root {
#SerializedName("Outer")
public Map<Integer, Outer> outer;
#Override
public String toString() {
return "Root[outer=" + this.outer + "]";
}
}
class Outer {
#SerializedName("Attr1")
public int attr1;
#SerializedName("Attr2")
public int attr2;
#Override
public String toString() {
return "Outer[attr1=" + this.attr1 + ", attr2=" + this.attr2 + "]";
}
}
Test
Gson gson = new GsonBuilder().create();
Root root;
try (BufferedReader in = Files.newBufferedReader(Paths.get("test.json"))) {
root = gson.fromJson(in, Root.class);
}
System.out.println(root);
Output
Root[outer={0=Outer[attr1=12345, attr2=67890], 1=Outer[attr1=54321, attr2=9876]}]
Get as Array
You can then add a helper method to the Root class to get that as an array:
public Outer[] getOuterAsArray() {
if (this.outer == null)
return null;
if (this.outer.isEmpty())
return new Outer[0];
int maxKey = this.outer.keySet().stream().mapToInt(Integer::intValue).max().getAsInt();
Outer[] arr = new Outer[maxKey + 1];
this.outer.forEach((k, v) -> arr[k] = v);
return arr;
}
Test
System.out.println(Arrays.toString(root.getOuterAsArray()));
Output
[Outer[attr1=12345, attr2=67890], Outer[attr1=54321, attr2=9876]]
Using Deserializer
However, it would likely be more useful if the conversion to array is done while parsing, so you need to write a JsonDeserializer and tell Gson about it using #JsonAdapter:
class Root {
#SerializedName("Outer")
#JsonAdapter(OuterArrayDeserializer.class)
public Outer[] outer;
#Override
public String toString() {
return "Root[outer=" + Arrays.toString(this.outer) + "]";
}
}
class OuterArrayDeserializer implements JsonDeserializer<Outer[]> {
#Override
public Outer[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// Parse JSON array normally
if (json.isJsonArray())
return context.deserialize(json, Outer[].class);
// Parse JSON object using names as array indexes
JsonObject obj = json.getAsJsonObject();
if (obj.size() == 0)
return new Outer[0];
int maxKey = obj.keySet().stream().mapToInt(Integer::parseInt).max().getAsInt();
Outer[] arr = new Outer[maxKey + 1];
for (Entry<String, JsonElement> e : obj.entrySet())
arr[Integer.parseInt(e.getKey())] = context.deserialize(e.getValue(), Outer.class);
return arr;
}
}
Same Outer class and test code as above.
Output
Root[outer=[Outer[attr1=12345, attr2=67890], Outer[attr1=54321, attr2=9876]]]
I'll asume your JsonObject is a POJO class such like:
public Inner[] outer;
If you want an array of objects you can change your code to:
Inner[] jo = gson.fromJson(json, Inner[].class);
Jackson – Marshall String to JsonNode will be useful in your case.with following pom:-
//POM FILE
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
//JAVA CODE
//read json file data to String
byte[] jsonData = Files.readAllBytes(Paths.get("employee.txt"));
//create ObjectMapper instance
ObjectMapper objectMapper = new ObjectMapper();
//read JSON like DOM Parser
JsonNode rootNode = objectMapper.readTree(jsonData);
JsonNode idNode = rootNode.path("id");
System.out.println("id = "+idNode.asInt());
JsonNode phoneNosNode = rootNode.path("phoneNumbers");
Iterator<JsonNode> elements = phoneNosNode.elements();
while(elements.hasNext()){
JsonNode phone = elements.next();
System.out.println("Phone No = "+phone.asLong());
}
You can use the JsonNode class's method findParent findValue and findPath which reduce your code as compare to another parsing library.
Please refer below code
1.To get an array of Objects (outerArray)
2.You can extract a JsonArray (outerJsonArray) containing values of inner objects in Outer (in case keys aren't significant for further use)
String json = "{\"Outer\": { \"0\": { \"Attr1\": 12345, \"Attr2\": 67890 }, \"1\": { \"Attr1\": 54321, \"Attr2\": 09876 }}}";
Gson gson = new GsonBuilder().disableHtmlEscaping().setLenient().serializeNulls().create();
JsonObject jo = gson.fromJson(json, JsonObject.class);
JsonObject outer = jo.getAsJsonObject("Outer");
Object[] outerArray = outer.entrySet().toArray();
// outerArray: [0={"Attr1":12345,"Attr2":67890}, 1={"Attr1":54321,"Attr2":"09876"}]
JsonArray outerJsonArray = new JsonArray();
outer.keySet().stream().forEach(key -> {
outerJsonArray.add(outer.get(key));
});
//jsonArray=[{"Attr1":12345,"Attr2":67890},{"Attr1":54321,"Attr2":"09876"}]
System.out.println(outer);
System.out.println(outerJsonArray.isJsonArray() + " " + outerJsonArray);
I want to use financial data from yahoo in my program, it already works. I get the complete JSON content and I can display it. But now I want to extract the price as int.
public class Main {
public static void main (String[]args) throws IOException {
String sURL = "http://finance.yahoo.com/webservice/v1/symbols/googl/quote?format=json"; //just a string
// Connect to the URL using java's native library
URL url = new URL(sURL);
HttpURLConnection request = (HttpURLConnection) url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //may be an array, may be an object.
System.out.print(rootobj);
}
}
EDIT
This is the JSON data from yahoo
{
"list" : {
"meta" : {
"type" : "resource-list",
"start" : 0,
"count" : 1
},
"resources" : [
{
"resource" : {
"classname" : "Quote",
"fields" : {
"name" : "Google Inc.",
"price" : "554.520020",
"symbol" : "GOOGL",
"ts" : "1432324800",
"type" : "equity",
"utctime" : "2015-05-22T20:00:00+0000",
"volume" : "1213288"
}
}
}
]
}
}
EDIT 2
I changed my code
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject obj = root.getAsJsonObject();
JsonObject result = obj.get("list").getAsJsonObject();
String result2 = result.get("resources").toString();
System.out.print(result2);
And now I already get this
[{"resource":{"classname":"Quote","fields":{"name":"Google Inc.","price":"554.520020","symbol":"GOOGL","ts":"1432324800","type":"equity","utctime":"2015-05-22T20:00:00+0000","volume":"1213288"}}}]
How can I get the "price" now?
EDIT 3
Ok I got it now, it works and I only get the price as double, but is this a smart way to solve this task?
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //convert the input stream to a json element
JsonObject obj = root.getAsJsonObject();
JsonObject result = obj.get("list").getAsJsonObject();
JsonArray result2 = result.get("resources").getAsJsonArray();
JsonObject result3 = result2.get(0).getAsJsonObject();
JsonObject result4 = result3.get("resource").getAsJsonObject();
JsonObject result5 = result4.get("fields").getAsJsonObject();
String result6 = result5.get("price").toString();
result6 = result6.replace("\"", "");
double value = Double.parseDouble(result6);
System.out.print(value);
you should reach "fields" object to extract "name", "price" etc.
The org.json library is easy to use. Example code below: your response as a string :
JSONObject obj1 = new JSONObject(response);
JSONArray arr = obj1.getJSONObject("list").getJSONArray("resources"); //GETS RESOURCES ARRAY
for (int i = 0; i < arr.length(); i++)
{
String resource = arr.getJSONObject(i).toString();
JSONObject obj2 = new JSONObject(resource);
String resourceObject = obj2.getJSONObject("resource").toString(); //RESOURCE OBJECT
JSONObject obj3 = new JSONObject(resourceObject);
String name = obj3.getJSONObject("fields").getString("name"); //REACHED THE FIELDS
float price = (float)obj3.getJSONObject("fields").getDouble("price");
System.out.println(name);
System.out.println(price);
}
Download : http://mvnrepository.com/artifact/org.json/json
He is already using gson.
If you want to continue using gson and know the structure before, you could create classes that stores the data.
class GoogleRequest{
private GoogleList list;
public GoogleList getList() {
return list;
}
public void setList(GoogleList list) {
this.list = list;
}
}
// class for list
class GoogleList{
private Meta meta;
private List<Resources> resources;
public List<Resources> getResources() {
return resources;
}
public void setResources(List<Resources> resources) {
this.resources = resources;
}
public Meta getMeta() {
return meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
}
// create other classes here like the Resources class
JsonParser jp = new JsonParser(); // from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream)request.getContent()));
GoogleRequest list = new Gson().fromJson(root,GoogleRequest.class);
The GoogleRequest should hold a List object and a Meta object. gson will introspect and set the properties. gson will set properties to null if they where not introspected. So you could use.
if( list.getResources() != null ){
// list is here
}else{
// do some other code and parse diffrent json
}
If you don't know if it is a array or object create different classes to handle it for you. Just parse the data with new Gson().fromJson();
Now remember that you need right properties for the job. Let's say you have this json in java
String json = "{\"price\" : \"554.520020\"}";
Then price needs to be Double or double. If you use Double you could check
if( obj.getPrice() != null ){
System.out.println( obj.getPrice().intValue() );
}
Note: you will loose precision if you cast double to int
I have a JSON response like this.
{
"array": [
{
"object1": {
"aa": "somevalue1",
"bb": "somevalue2",
"cc": "somevalue3"
}
},
{
"object2": {
"aa": "somevalue4",
"bb": "somevalue5",
"cc": "somevalue6"
}
}
]}
Now I can get a JSON array from above response. I want read the value aa,bb,cc from object object1 and object2 in a for loop.
JSON is dynamic, I mean that object2 can also appear before object1 (in reverse order) and there is chances that I might get one more object(object3) with same structure OR only one (object1 or object2 or object3).
I dont want to do like this as I failed in :
JSONArray jsonArray = json.getJSONArray("array");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i).getJSONObject("object1");
}
So my question is HOW can I read those values aa,bb,cc without depending on object name or number of object (object1 or object2 or object3)?
It looks like each item in the array only has 1 key/value pair which holds another json object which then has several.
If this is the case, then you could probably do something like this:
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONObject innerObject = jsonObject.getJSONObject(jsonObject.keys().next().toString());
/// do something with innerObject which holds aa, bb, cc
}
You simply grab the 1st key in the wrapping object, and use that to grab the inner json object.
I think you should have next Java-side structure of classes:
Entity - class that will hold aa, bb and cc fields
Container - a class that will consist of two fields - Name and Entity, where Name can store object1, object2 or whatever.
Then, you should deserialize provided JSON into collection/array of Container entities.
Hope this helps.
Update: please check this example Collection deserialization
You should work with dynamic structures like java.util.Map. Try with this:
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
public class JsonTest {
public static void main(String[] args) {
String json = "{\"array\": [{\"object1\": {\"aa\": \"somevalue1\",\"bb\": \"somevalue2\",\"cc\": \"somevalue3\"}},{\"object2\": {\"aa\": \"somevalue4\",\"bb\": \"somevalue5\",\"cc\": \"somevalue6\"}}]}";
System.out.println(json);
final MyJson parseJsonSpecification = parseJsonSpecification(json);
System.out.println(parseJsonSpecification.array.get(0).get("object1"));
System.out.println(parseJsonSpecification);
}
public static MyJson parseJsonSpecification(String jsonString) {
try {
if (StringUtils.isBlank(jsonString)) {
return new MyJson();
}
MyJson ret;
ret = new ObjectMapper().readValue(jsonString, new TypeReference<MyJson>() {
});
return ret;
} catch (Exception ex) {
throw new IllegalArgumentException("La expresión '" + jsonString + "' no es un JSON válido", ex);
}
}
}
class MyJson {
public List<Map<String, Object>> array;
}
I have a JSON string like this of data for a table in an android app. one of {} is a row of data for the table. I want to separate these {}s into an array and then each element inside this array into other sub-arrays separating other elements inside {}. Please suggest an appropriate way of accomplishing this criteria using JSON. Thank you.
[
{
"nodeName":"prime_mtsc22#smpp3",
"nodeId":"MTSC3",
"tidPrefix":"4",
"optStatus":"offline",
"daStart":"1",
"daEnd":"3",
"description":"Description"
},
{
"nodeName":"prime_mtsc22#smpp2",
"nodeId":"MTSC58",
"tidPrefix":"1",
"optStatus":"blocked",
"daStart":"5",
"daEnd":"10",
"description":"new description"
},
{
"nodeName":"prime_mtsc22#smpp1",
"nodeId":"MTSC1",
"tidPrefix":"15",
"optStatus":"online",
"daStart":"12",
"daEnd":"20",
"description":"Description"
},
{
"nodeName":"prime_mtsc22#smpp0",
"nodeId":"MTSC15",
"tidPrefix":"15",
"optStatus":"offline",
"daStart":"25",
"daEnd":"30",
"description":"Description"
}
]
ok so in that case the code to use is this
String jsonString = <your jsonString>;
// THIS IS NOT NEEDED ANYMORE
//JSONObject json = new JSONObject(jsonString);
JSONArray topArray = null;
try {
// Getting your top array
// THIS IS NOT NEEDED ANYMORE
//topArray = json.getJSONArray(jsonString);
//use this instead
topArray = new JSONArray(jsonString);
// looping through All elements
for(int i = 0; i < topArray.length(); i++){
JSONObject c = topArray.getJSONObject(i);
//list holding row data
List<NodePOJO> nodeList = new ArrayList<NodePOJO>();
// Storing each json item in variable
String nodeName = c.getString("nodeName");
String nodeID = c.getString("nodeID");
NodePOJO pojo = new NodePOJO();
pojo.setNodeName(nodeName);
//add rest of the json data to NodePOJO class
//the object to list
nodeList.add(pojo);
}
} catch (JSONException e) {
e.printStackTrace();
}
ok?
Use JSONObject for this http://developer.android.com/reference/org/json/JSONObject.html
Example
String jsonString = <your jsonString>;
JSONObject json = new JSONObject(jsonString);
JSONObject topArray = ;
try {
// Getting your top array
topArray = json.getJSONArray(TAG_ARRAY_TOP);
// looping through All elements
for(int i = 0; i < topArray.length(); i++){
JSONObject c = topArray.getJSONObject(i);
//list holding row data
List<NodePOJO> nodeList = new ArrayList<NodePOJO>();
// Storing each json item in variable
String nodeName = c.getString("nodeName");
String nodeID = c.getString("nodeID");
NodePOJO pojo = new NodePOJO();
pojo.setNodeName(nodeName);
//add rest of the json data to NodePOJO class
//the object to list
nodeList.add(pojo);
}
} catch (JSONException e) {
e.printStackTrace();
}
Use the NodePOJO class to hold each row values.
public class NodePOJO {
private String nodeName;
// do for rest of the json row data
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
public String getNodeName() {
return this.nodeName;
}
}
I am fairly new to JSON parser and I am trying to extract all data set from "sizes" tag i.e extracting values (small, yes, xsmall, NO, Medium and yes) from the JSON file in a complex nested loop but doesn't work. I am using GSON to parse the JSON file and using JAVA as programming language
Here how the JSON file looks like in general
{ response: "ok",
prodinfo: {
sizes: [
{ size:"small",
available: "yes"
},
{ size:"xsmall",
available: "No"
},
{ size:"Medium",
available: "yes"
}
]
}
}
This is what i did
int array = jsonParser14.parse(json14).getAsJsonObject().get("ProdInfo").getAsJsonObject().getAsJsonArray("sizes").size();
JsonArray sizes = (JsonArray) jsonParser15.parse(json15).getAsJsonObject().get("ProdInfo").getAsJsonObject().getAsJsonArray("sizes");
for (int i = 0; i <= array; i++) {
String size = sizes.get(i).getAsString();
System.out.println("data extracted are: " + size);
}
Your help will be appreciated.
Thanks
I usually treat this by making a public class with required fields :
public class ProdSize {
public String size;
public String available;
}
public class ProdInfo {
public ProdSize[] sizes;
}
public class Message {
public String response;
public ProdInfo prodinfo;
}
And then I just have to do this in gson :
Gson gson = new GsonBuilder().create();
Message mess = gson.fromJson(theJsonString, Message.class);
Then, I don't have any loop to do to parse the JSON. I directly have my sizes in
mess.prodinfo.sizes
For example you can print them like this
for (int i=0; i<mess.prodinfo.sizes.length; i++) {
ProdSize size = mess.prodinfo.sizes[i];
System.out.println("Size " + size.size + " -> " + size.available);
}
Something like:
var sizes = json.prodinfo.sizes;
for (item in sizes) {
if (sizes.hasOwnProperty(item)) {
var isAvailable = sizes[item].available;
alert(isAvailable);
}
}
Example here: http://jsfiddle.net/nG88B/3/
Edit:
Looks like you need to parse the JSON first. In which case (if it's valid) you can do:
var obj = JSON.parse(jsonStr);