[英]JSON parsing using Jettison
我试图使用Jettison解析JSON对象。 这是我正在使用的代码
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;
}
我收到了这个错误
线程“main”中的异常javax.xml.bind.UnmarshalException - 带有链接异常:[javax.xml.bind.UnmarshalException:unexpected element(uri:“”,local:“appUsage”)。 com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl的com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(未知来源)中的预期元素为(none)]。 un comrshal0(未知来源)com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(未知来源)com.json.UnmarshalDemo.jsonParser(UnmarshalDemo.java:56)com.json.UnmarshalDemo .main(UnmarshalDemo.java:33)引起:javax.xml.bind.UnmarshalException:意外元素(uri:“”,local:“appUsage”)。 com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError中的com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(未知来源)中的预期元素为(无)。 (未知来源)com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(未知来源)com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(未知来源)来自com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext $ defaultRootLoader.childElement(未知来源)com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(未知)来自com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(未知来源)的com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(未知来源)在com.sun.xml.internal.bind.v2.runtime.unmarshall的com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(未知来源) er.StAXStreamConnector.bridge(未知来源)... 4更多引起:javax.xml.bind.UnmarshalException:意外元素(uri:“”,local:“appUsage”)。 预期的要素是(无)......还有14个
如何解决这个问题
注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB 2(JSR-222)专家组的成员。
如果您最终正在寻找使用JAXB(JSR-222)实现与JSON交互的方法,那么以下是使用MOXy完成它的方法。 Jettison是一个有趣的库,但是你会遇到一些问题:
演示
仅使用标准Java SE API。 需要在Unmarshaller
上设置两个MOXy特定属性: "eclipselink.media-type"
指定"application/json"
, "eclipselink.json.include-root"
指示没有根节点。
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);
}
}
}
根
我不得不介绍这个课程来满足你的用例。 如果你的JSON看起来像我们可以消除这个类: [{"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
要将MOXy指定为JAXB提供程序,您需要添加一个名为java.properties
的文件,并在与您的域类相同的包中添加以下条目:
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
产量
以下是运行演示代码的输出:
ANDROID 0
IOS 4
欲获得更多信息
使用@XmlRootElement注释您的类MiAppUsage(name =“appUsage”,namespace =“”)
例如: - @XmlRootElement(name =“appUsage”,namespace =“”)public class MiAppUsage {
}
我认为Jettison无法做到这一点。 看起来像JSONObject
不喜欢具有数组作为其值的根元素。 如果它是一个选项,您可以将输入更改为JSON数组,可以使用Jettison进行解析:
public static void main(String[] args) throws Exception {
String s ="[{\"appUsage\":{\"appName\":\"ANDROID\",\"totalUsers\":\"0\"}},{\"appUsage\":{\"appName\":\"IOS\",\"totalUsers\":\"4\"}}]";
JSONArray arr = new JSONArray(s);
List<MiAppUsage> list = unmarshal(MiAppUsage.class, arr);
for(MiAppUsage miAppUsage : list) {
System.out.println(miAppUsage.appName + ": " + miAppUsage.totalUsers);
}
}
public static <T> List<T> unmarshal(Class<T> cls, JSONArray arr) throws JSONException, XMLStreamException, JAXBException {
List<T> list = new ArrayList<T>();
for (int i = 0; i < arr.length(); i++) {
list.add(unmarshal(cls, arr.getJSONObject(i)));
}
return list;
}
public static <T> T unmarshal(Class<T> cls, JSONObject obj) throws JSONException, XMLStreamException, JAXBException {
JAXBContext jc = JAXBContext.newInstance(cls);
Configuration config = new Configuration();
MappedNamespaceConvention con = new MappedNamespaceConvention(config);
XMLStreamReader xmlStreamReader = new MappedXMLStreamReader(obj, con);
Unmarshaller unmarshaller = jc.createUnmarshaller();
return cls.cast(unmarshaller.unmarshal(xmlStreamReader));
}
这打印:
ANDROID: 0
IOS: 4
带有JAXB注释的模型类是这样的:
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "appUsage")
@XmlAccessorType(XmlAccessType.FIELD)
public class MiAppUsage {
String appName;
int totalUsers;
}
作为Jettison的替代品,您可以使用StAXON的JsonXMLMapper
轻松解析您的原始JSON输入,该JsonXMLMapper
适用于任何JAXB实现:
String s ="{\"appUsage\":[{\"appName\":\"ANDROID\",\"totalUsers\":\"0\"},{\"appName\":\"IOS\",\"totalUsers\":\"4\"}]}";
JsonXMLMapper<MiAppUsage> mapper = new JsonXMLMapper<MiAppUsage>(MiAppUsage.class);
List<MiAppUsage> list = mapper.readArray(new StringReader(s));
for(MiAppUsage miAppUsage : list) {
System.out.println(miAppUsage.appName + ": " + miAppUsage.totalUsers);
}
有关StAXON的JAXB支持的更多信息,请参阅使用JAXB wiki页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.