I am trying to parse JSON object using Jettison. This the code I'm using
String s ="{\"appUsage\":[{\"appName\":\"ANDROID\",\"totalUsers\":\"0\"},{\"appName\":\"IOS\",\"totalUsers\":\"4\"}]}";
JSONObject obj = new JSONObject(s);
ArrayList<MiAppUsage> l1 = (ArrayList<MiAppUsage>) jsonParser(ArrayList.class, obj);
public static Object jsonParser(Class c, JSONObject obj)
throws JSONException, XMLStreamException, JAXBException {
JAXBContext jc = JAXBContext.newInstance(c);
Configuration config = new Configuration();
MappedNamespaceConvention con = new MappedNamespaceConvention(config);
XMLStreamReader xmlStreamReader = new MappedXMLStreamReader(obj, con);
Unmarshaller unmarshaller = jc.createUnmarshaller();
ArrayList<MiAppUsage>customer = (ArrayList<MiAppUsage>) unmarshaller.unmarshal(xmlStreamReader);
return customer;
}
I'm getting this error
Exception in thread "main" javax.xml.bind.UnmarshalException - with linked exception: [javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"appUsage"). Expected elements are (none)] at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source) at com.json.UnmarshalDemo.jsonParser(UnmarshalDemo.java:56) at com.json.UnmarshalDemo.main(UnmarshalDemo.java:33) Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"appUsage"). Expected elements are (none) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(Unknown Source) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(Unknown Source) ... 4 more Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"appUsage"). Expected elements are (none) ... 14 more
How to resolve this problem
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
If you are ultimately looking for a way to interact with JSON using a JAXB (JSR-222) implementation, then the following is how it can be done using MOXy. Jettison is an interesting library but there are some issue you will encounter using it:
Demo
Only the standard Java SE APIs are used. There are two MOXy specific properties that need to be set on the Unmarshaller
: "eclipselink.media-type"
to specify "application/json"
, and "eclipselink.json.include-root"
to indicate that there is no root node.
package forum9924567;
import java.io.StringReader;
import java.util.ArrayList;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
public class Demo {
private static final String s ="{\"appUsage\":[{\"appName\":\"ANDROID\",\"totalUsers\":\"0\"},{\"appName\":\"IOS\",\"totalUsers\":\"4\"}]}";
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setProperty("eclipselink.media-type", "application/json");
unmarshaller.setProperty("eclipselink.json.include-root", false);
StreamSource json = new StreamSource(new StringReader(s));
Root root = unmarshaller.unmarshal(json, Root.class).getValue();
ArrayList<MiAppUsage> customer = root.appUsage;
for(MiAppUsage miAppUsage : customer) {
System.out.print(miAppUsage.appName);
System.out.print(' ');
System.out.println(miAppUsage.totalUsers);
}
}
}
Root
I had to introduce this class to meet your use case. We could eliminate this class if your JSON looked like: [{"appName":"ANDROID","totalUsers":"0"},{"appName":"IOS","totalUsers":"4"}]
.
package forum9924567;
import java.util.ArrayList;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
ArrayList<MiAppUsage> appUsage;
}
MiAppUsage
package forum9924567;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class MiAppUsage {
String appName;
int totalUsers;
}
jaxb.properties
To specify MOXy as your JAXB provider you need to add a file called java.properties
with the following entry in the same package as your domain classes:
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
Output
The following is the output from running the demo code:
ANDROID 0
IOS 4
For More Information