为对象显示 null -JSON- JAXB

Posted

技术标签:

【中文标题】为对象显示 null -JSON- JAXB【英文标题】:Display null for objects -JSON- JAXB 【发布时间】:2011-04-25 16:40:31 【问题描述】:

我想在 JSON 表示中将 null 对象编组为 null。 但是,现在,如果对象为空,我看不到 JSON 中的元素。

Example:
@XmlAccessType(FIELD)
@XmlType(name="foo" propOrder="foo"
class foo
@XmlElement
      private Integer foo;
      private Integer another_foo;
..

getter()
setter()


在我的代码中,我将 foo 元素设置为 null。

但 JSON 表示不显示响应中的元素。

响应如下所示

"foo" :
 "another_foo":something

我尝试将 xml 元素属性设置为 nillable true。 (@XmlElement(nillable=true)

这使响应看起来像,

"foo" :
 "another_foo" : something
 "foo":nil :true

我希望它像,

    "foo" :
     "another_foo":something
     "foo" : null
    

这里做错了什么?

【问题讨论】:

【参考方案1】:

我认为 json 的功能只是这样,它不会在 Json 字符串中显示空值。假设一个示例,您有一个具有两个属性的对象,即年龄和姓名。现在,如果年龄为 7 岁且名称为空,那么如果根据您的说法,名称也应该包含在 JSON 对象中,那么您必须正确处理代码以显式处理相同代码的反序列化。那么您将不得不处理空值的事情,因为 JSON 会将“null”视为字符串并将其分配给对象,这将使您的对象具有 name="null",这是错误的。

如果你想达到同样的效果,那么你必须扩展类 JSON 对象并编写你自己的实现。

【讨论】:

不,JSON 有明确的 null 值,所以这不是 JSON 造成的。而是由于处理 JAXB 注释,以及它如何选择处理 Java 对象的空值。【参考方案2】:

第一件事:JAXB 不做 JSON。它是一个 XML API。所以你可能正在使用一个框架(我的猜测:JAX-RS 实现,比如 Jersey)?有必要知道您正在使用哪一个来提供更多帮助。

假设这一点,问题是,包如何使用 JAXB 注释来指导 JSON 序列化。有些基本上将对象转换为 XML(逻辑结构或完整的 xml),然后使用约定转换为 JSON。由于 XML 和 JSON 之间的数据模型不同,这可能会导致数据丢失。

现在:大多数 JAX-RS 实现的简单解决方案是根本不使用基于 JAXB 注释的方法,而是使用特定于 JSON 的序列化器,例如 Jackson 的 JacksonJsonProvider(Jackson 实际上也可以使用 JAXB 注释)。默认情况下,它会包含属性的 null 值,尽管这可以配置以防您想抑制 null。

这里是JavaDoc,它展示了如何在 Jersey 中使用 Jackson 提供程序(指定 FEATURE_POJO_MAPPING 进行配置),如果这可能有帮助的话。

【讨论】:

感谢 Staxman,是的,我们正在使用 Jackson JSON 提供程序。我在想应该有办法使用 JAXB 注释。我会试试这个。 啊。也许 Jersey 只是默认配置 ObjectMapper 来抑制空值?虽然默认设置不这样做,但 Jersey 可以选择覆盖这种保持行为,类似于其他序列化程序。无论如何,调用方法在 SerializationgConfig (setSerializationInclusion) 中,可以使用 ObjectMapper.getSerializationConfig() 访问。还有注解@JsonSerialize 可用于定义每个类的包含(全部、非空、非默认)。【参考方案3】:

注意:我是EclipseLink JAXB (MOXy) 的负责人和JAXB (JSR-222) 专家组的成员。

EclipseLink JAXB (MOXy) 提供对 JSON 的本机支持。以下是如何利用 @XmlElement 注释来映射您的用例的示例:

Foo

默认情况下,JAXB 实现不会封送空属性。您可以通过将 @XmlElement 上的 nillable 属性设置为 true 来更改此行为。

package forum3938279;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
class Foo 
      @XmlElement(nillable=true)
      private Integer foo;
      private Integer another_foo;


jaxb.properties

要将 MOXy 指定为您的 JAXB 提供程序,您必须在与您的域模型相同的包中包含一个名为 jaxb.properties 的文件,其中包含以下条目:

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

演示

package forum3938279;

import javax.xml.bind.*;

public class Demo 

    public static void main(String[] args) throws Exception 
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        Foo foo = new Foo();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty("eclipselink.media-type", "application/json");
        marshaller.marshal(foo, System.out);
    


输出

下面是运行演示代码的输出。这两个字段都有空值。没有@XmlElement 注释的字段未编组,而带有@XmlElement(nillable=true) 的字段在JSON 中按预期进行了编组。


   "foo" : null

更多信息

http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html

【讨论】:

为什么可空而不可空? Nil 通常为零,与 null 不同。

以上是关于为对象显示 null -JSON- JAXB的主要内容,如果未能解决你的问题,请参考以下文章

JAXB解析XML为对象

在将 XML 文件解组为对象后,如何让 JAXB 调用方法?

使用 jaxb 将对象转换为 XML 的异常

当节点包含值时,使用 JAXB 将 XML 转换为对象

如何获取JAXB对象的命名空间

JAXB Unmarshal 创建一个空对象