首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Jettison的JSON解析

使用Jettison的JSON解析
EN

Stack Overflow用户
提问于 2012-03-29 11:37:28
回答 3查看 11.9K关注 0票数 4

我正在尝试使用Jettison解析JSON对象。这是我使用的代码

代码语言:javascript
复制
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:意外元素(uri:"",local:"appUsage")。预期的元素是(在com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(Unknown源)在com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown源)在com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown源)在com.json.UnmarshalDemo.jsonParser(UnmarshalDemo.java:56) ( com.json.UnmarshalDemo.main(UnmarshalDemo.java:33 ))由: javax.xml.bind.UnmarshalException:意外元素(uri:"",本地:“appUsage”)。预期元素在com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(Unknown源)在com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown源)在com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown源)在com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Unknown源)在com.sun( .xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(Unknown源代码)( com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(Unknown Source) )( com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(Unknown源代码))在com.sun.xml.interlin.bind.v2运行时。( unmarshaller.StAXStreamConnector.handleStartElement(Unknown来源)在com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(Unknown源代码中).4由: javax.xml.bind.UnmarshalException:意外元素(uri:"",本地:“appUsage”)。预期因素(无).多14项

如何解决这一问题

EN

回答 3

Stack Overflow用户

发布于 2012-03-29 18:30:42

备注:,我是EclipseLink JAXB (MOXy)的负责人,也是JAXB 2 (JSR-222)专家组的成员。

如果您最终希望找到一种使用JAXB (JSR-222)实现与JSON交互的方法,那么下面是如何使用MOXy进行交互的方法。Jettison是一个有趣的库,但是在使用它时会遇到一些问题:

  • http://blog.bdoughan.com/2011/04/jaxb-and-json-via-jettison.html

Demo

只使用标准的Java。需要在MOXy上设置两个特定于Unmarshaller的属性:"eclipselink.media-type"指定"application/json""eclipselink.json.include-root"表示没有根节点。

代码语言:javascript
复制
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"}],我们可以消除这个类。

代码语言:javascript
复制
package forum9924567;

import java.util.ArrayList;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    ArrayList<MiAppUsage> appUsage;

}

MiAppUsage

代码语言:javascript
复制
package forum9924567;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class MiAppUsage {

    String appName;
    int totalUsers;

}

jaxb.properties

要将MOXy指定为JAXB提供程序,需要在与域类相同的包中添加一个名为java.properties的文件,其中包含以下条目:

代码语言:javascript
复制
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory

输出

以下是运行演示代码的输出:

代码语言:javascript
复制
ANDROID 0
IOS 4

获取更多信息

  • http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html
  • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
票数 5
EN

Stack Overflow用户

发布于 2012-03-30 13:18:43

我认为抛锚是办不到的。似乎JSONObject不喜欢以数组作为其值的根元素。如果这是一个选项,您可以将输入更改为JSON数组,该数组可以用Jettison解析:

代码语言:javascript
复制
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));
}

这些指纹:

代码语言:javascript
复制
ANDROID: 0
IOS: 4

JAXB注释的模型类如下所示:

代码语言:javascript
复制
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "appUsage")
@XmlAccessorType(XmlAccessType.FIELD)
public class MiAppUsage {
  String appName;
  int totalUsers;
}

作为舍弃JSON的另一种选择,您的原始JSON输入可以很容易地用StAXONJsonXMLMapper解析,该JsonXMLMapper适用于任何JAXB实现:

代码语言:javascript
复制
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页面。

票数 0
EN

Stack Overflow用户

发布于 2014-07-15 13:46:14

用@XmlRootElement注释类MiAppUsage (name= "appUsage",namespace="")

@XmlRootElement(name = "appUsage",namespace=“)公共类MiAppUsage {

}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9924567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档