【问题标题】:Marshalling the Java objects (without @XmlRootElement) to JSON via Jettison通过 Jettison 将 Java 对象(不带 @XmlRootElement)编组为 JSON
【发布时间】:2013-03-02 09:52:49
【问题描述】:

我已经使用 Jettison 将 JAXB 对象(包含 @XmlRootElement)编组为 JSON。但我无法将没有 @XmlRootElement 等注释的简单 java 对象转换为 JSON。我想知道“是否必须让 @XmlRootElement 将对象编组为 JSON?”

当我尝试将 java 对象编组为 Json 时出现以下异常

com.sun.istack.SAXException2: unable to marshal type "simpleDetail" as an element because it is missing an @XmlRootElement annotation

可能是什么问题?

【问题讨论】:

  • 看起来您可能需要@XmlRootElement,至少根据错误消息。但你可以使用XStream 的 JSON 序列化来绕过它。
  • @hd1 :感谢您的回复。是的,我们可以做到。如果我们使用 XStream 或 GS​​ON。但我只需要使用 Jettison 来做到这一点。这里不可能吗?

标签: java json jakarta-ee jaxb jettison


【解决方案1】:

请阅读@XmlRootElement 并不总是必要的。请阅读this blog,在底部您会发现没有@XmlRootElement 是如何完成的。 还可以查看No @XmlRootElement generated by JAXB 帖子中的答案。

【讨论】:

    【解决方案2】:

    注意:我是EclipseLink JAXB (MOXy) 领导,也是JAXB (JSR-222) 专家组的成员。

    JAXB (JSR-222) 规范不包括 JSON 绑定。您可以使用提供本机 JSON 绑定的 EclipseLink JAXB (MOXy),而不是使用 Jettison 库的 JAXB 实现。下面是一个例子。

    JAVA 模型

    Foo

    import java.util.List;
    import javax.xml.bind.annotation.*;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Foo {
    
        private List<Bar> mylist;
    
    }
    

    条形

    import javax.xml.bind.annotation.*;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Bar {
    
        private int id;
        private String name;
    
    }
    

    jaxb.properties

    要将 MOXy 指定为您的 JAXB 提供程序,您需要在与域模型相同的包中包含一个名为 jaxb.properties 的文件,并使用以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    演示代码

    演示

    MOXy 不需要@XmlRootElement 注释,您可以使用JSON_INCLUDE_ROOT 属性告诉MOXy 忽略任何@XmlRootElement 注释的存在。当根元素被忽略时,您需要使用 unmarshal 方法,该方法采用类参数来指定要解组的类型。

    import java.util.*;
    import javax.xml.bind.*;
    import javax.xml.transform.stream.StreamSource;
    import org.eclipse.persistence.jaxb.JAXBContextProperties;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            Map<String, Object> properties = new HashMap<String, Object>(2);
            properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
            properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
            JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            StreamSource json = new StreamSource("src/forum15404528/input.json");
            Foo foo = unmarshaller.unmarshal(json, Foo.class).getValue();
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(foo, System.out);
        }
    
    }
    

    input.json/Output

    我们看到输入或输出中没有根元素。

    {
       "mylist" : [ {
          "id" : 104,
          "name" : "Only one found"
       } ]
    }
    

    其他信息

    【讨论】:

    • @BDoughan:是的,我已经用 eclipseLink 试过了,效果很好。但我需要使用 JETTISON 来实现它:( .Plz 指导我使用 JETTISON 来实现它。
    • @user1933756 - 我不确定 Jettison 是否可行。我已经编辑了您的问题标题和标签以包含 Jettison 以尝试吸引您正在寻找的答案。
    • 谢谢你 Blaise:我读过这个blog.bdoughan.com/2011/04/jaxb-and-json-via-jettison.html。这里使用 JETTISON 完成
    • @user1933756 - 我不确定你是否注意到了,但那篇文章来自我的博客。
    • 是的 :) 它来自您的博客。我想确认它是否纯粹使用 JETTISON 完成?
    猜你喜欢
    • 1970-01-01
    • 2011-12-19
    • 2013-03-03
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 2018-01-20
    相关资源
    最近更新 更多