I'm new to JSON manipulation in Java and I have a String in the form of a JSON Array with several layers I need to access and put into class attributes. For example, here's my JSON object:
{"JsonObject" : [{"attributeOne":"valueOne",
"attributeTwo":"valueTwo",
"attributeThree":[{"subAttributeOne":"subValueOne",
"subAttributeTwo":"subValueTwo"}],
"attributeFour":[{"subAttributeOne":"subValueThree",
"subAttributeTwo":"subValueFour"}],
"attributeFive":"valueThree"},
{"attributeOne":"valueFour",
"attributeTwo":"valueFive",
"attributeThree":[{"subAttributeOne":"subValueFive",
"subAttributeTwo":"subValueSix"}],
"attributeFour":[{"subAttributeOne":"subValueSeven",
"subAttributeTwo":"subValueEight"}],
"attributeFive":"valueSix"}]}
Lets say I have a class called MyClass that has these attributes, how would i parse this string, knowing this is an array of n Objects, each containing "attributeOne, attributeTwo, ..., attributeFive"?
Here's what I have so far:
public MyClass[] jsonToJava (String jsonObj)
{
ArrayList<MyClass> myClassArray = new ArrayList<MyClass>();
//Somehow create a JSONArray from my jsonObj String
JSONArray jsonArr = new JSONArray(jsonObj); //Don't know if this would be correct
for(int i=0; i<jsonArr.length; i++){
MyClass myClassObject = new MyClass();
myClassObject.setAttributeOne = jsonArr[i].getString("attributeOne");
// How can I access the subAttributeOne and Two under attributeThree and Four?
// add all other values to myClassObject
myClassArray.add(myClassObject);
}
return myClassArray;
}
As you can probably tell, I'm fairly new to programming :P Thanks in advance for the help!
3 Answers 3
Try Jackson JSON:
ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
User user = mapper.readValue(jsonObj, User.class); //method overloaded to take String
grabbed this two liner from:
http://wiki.fasterxml.com/JacksonInFiveMinutes
http://jackson.codehaus.org/0.9.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html
Should convert your JSON strong to an object. In a Java EE context you may be able to get this unmarshalling functionality at an endpoint with the appropriate annotation.
Comments
The way you are trying to do it is painful and involved.
I would suggest that you use a library like GSON and let it do the heavy lifting. http://code.google.com/p/google-gson/
The documentation has object examples: https://sites.google.com/site/gson/gson-user-guide#TOC-Object-Examples
Comments
For your example you can use recursion something like:
public Object getChild(Object parent, int index) {
if (parent instanceof JSONArray) {
try {
Object o = ( (JSONArray)parent ).get(index);
if( o instanceof JSONObject ){
parent = ((JSONObject) ( o ) ).getMap();
return parent;
}
if( o instanceof Double ){
parent = (Double) o;
return parent;
}
if( o instanceof Integer ){
parent = (Integer) o;
return parent;
}
....
} catch (JSONException e1) {
e1.printStackTrace();
}
}
if (parent instanceof JSONObject) {
parent = ( (JSONObject)parent ).getMap();
}
if (parent instanceof Map<?, ?>) {
Map<?, ?> map = (Map<?, ?>) parent;
Iterator<?> it = map.keySet().iterator();
for (int i=0; i<index; i++){
it.next();
}
return map.get(it.next());
}
else if (parent instanceof Collection<?>) {
Iterator<?> it = ((Collection<?>) parent).iterator();
for (int i=0; i<index; i++){
it.next();
}
return it.next();
}
//throw new IndexOutOfBoundsException("'" + parent + "'cannot have children!");
return null;
}
But its a bit complicated (+bad practice to use instanceof) and you don't want to reinvent the wheel. So use GSON or Jackson.
Gson gson = new Gson();
String myClassStr = gson.toGson(MyClassInstance);
....
Myclass yourClass = gson.fromJson(myClassStr, Myclass.class);
GSON? its simple and fast. You just convert all your class to String and vise versa.