【问题标题】:JAXB Marshalling with null fields带有空字段的 JAXB 编组
【发布时间】:2010-10-25 21:47:38
【问题描述】:

这是一个非常简单的请求,但我只是没有找到方法。

我基本上是在尝试在 JAXB 中设置一个角色,即每当遇到空字段时,而不是在输出中忽略它,而是将其设置为空值。所以对于班级:

@XMLRootElement
Class Foo {
   Integer num;
   Date date;
….
}

如果日期字段为空,则将其编组到 XML 文件中时,我的输出中没有该元素。我想要做的是在输出中包含所有字段;如果它们为空,请将它们替换为 - 说一个空白。所以输出应该是:

<foo>
  <num>123</num>
  <date></date>
</foo>

谢谢,

贾尔佩什。

【问题讨论】:

  • 很好的问答!我遇到了同样的问题,这是一个巨大的帮助。

标签: java jaxb marshalling


【解决方案1】:

谢谢大家的回答。

Chris Dail - 我尝试了你的方法,但它并没有真正达到我想要的效果。尽管为我的字段定义了默认值,但 JAXB 仍然忽略了我的 null 值。

在泽西岛论坛中有人向我指出文档部分 2.2.12.8 No Value 后,我确实偶然发现了答案。

基本上,我所要做的就是将以下内容添加到我的字段中:

@XmlElement(nillable = true) 

添加后,JAXB 会在将这些字段编组为 XML 时显示这些字段,如下所示:

...
<num>5</num>
<date xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
....

【讨论】:

【解决方案2】:

但是但是但是……空字符串不是日期的有效词法表示,所以你不能这样做。即,如果您生成的 XML 文档的日期字段为空值,它将无法正确验证。

换句话说,如果您的date 元素有一个或多个minOccurs 而不是nillable,那么您绝对必须有(1 个或多个)日期,不能为空(或空白,或其他非值)。

【讨论】:

  • 我曾经将这个答案的第一段作为评论(感谢支持它的可爱的人!),但我认为它作为答案会更有用,现在我'对此进行了一些扩展。 :-)
  • 同意,但我没有验证 xml,而且它没有架构。拥有所有字段将使最终消费者更容易弄清楚这个 xml 的含义。在你开始指责我没有 xml 模式之前:) 我在另一个框架(Jersey)中使用它,它使用我的数据对象并使用 JAXB 吐出 XML/Json。所以我唯一的控制是对我的数据对象。此外,我可以看到支持空值的原因。考虑一个用例,我想从我的数据对象中生成一个 CSV 文件。我可以使用 marshal.marshal(elem, myContentHandler)。
  • contentHandler 然后会生成正确格式的 CSV 文件,只有在我的数据字段都没有被忽略的情况下才能完成。
【解决方案3】:

如另一个答案所示,它是无效的,因为它不是有效的日期。我有一个类似的问题,我想特别处理(相同)。由于不能使用 null,因此可以使用 JAXB 中的默认值机制。如果未指定,以下将默认值。您可以通过代码检测这个特殊日期并处理这个异常情况。

@XmlElement(defaultValue="1970-01-01T00:00:00.0-00:00")

因此可以检测并清空日期值,但您不能使用 null 来执行此操作。

【讨论】:

    【解决方案4】:

    在 MOXy 中,您可以指定 jsonProvider 必须如何为 JAXB 完成工作。

    所以在进行 JAX-RS 时,请在从 Application 派生的类中添加以下代码

    我在 Tomcat 7 上使用了这段代码,效果很好。 (eclipselink 2.4.1)

    @ApplicationPath("/rest")
    public class RestApplication extends Application
    {
    
      ...
    
     public Set< Object> getSingletons()
      {
    
        HashSet<Object> set = new HashSet<Object>(1);
        set.add( newMoxyJsonProvider());
    
        return set;
      }
    
    
     public static MOXyJsonProvider newMoxyJsonProvider()
      {
    
        MOXyJsonProvider result = new MOXyJsonProvider();
    
        //result.setAttributePrefix("@");
        result.setFormattedOutput( false);
        result.setIncludeRoot( false);
        result.setMarshalEmptyCollections( true);
        //result.setValueWrapper("$");
    
        return result;
      }
    

    然而,在 Glassfish 3.1.2 和 WAS 8.5 上,不需要 newMoxyJsonProvider(),但是 JAXB 提供程序由服务器配置。 对于 MOXy 附带的 Glassfish,我目睹了同样的空值问题。 尚未检查,但猜测答案是尽可能在应用程序服务器级别配置 JAXB。

    【讨论】:

    • confused 这个问题不是关于 JSON,而是关于 XML。
    【解决方案5】:

    试试这个:

    marshal.setListener(new MarshallerListener());
    

    public class MarshallerListener extends Marshaller.Listener {
    
        public static final String BLANK_CHAR = "";
    
        @Override
        public void beforeMarshal(Object source) {
            super.beforeMarshal(source);
            Field[] fields = source.getClass().getDeclaredFields();
            for (Field f : fields) {
                f.setAccessible(true);
                try {
                    if (f.getType() == String.class && f.get(source) == null) {
                        f.set(source, BLANK_CHAR);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多