48

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

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

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

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

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

谢谢,

贾尔佩什。

4

5 回答 5

40

谢谢你们的回答。

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

在泽西论坛中有人向我指出文档部分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"/>
....
于 2009-05-13T22:55:12.133 回答
4

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

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

于 2009-05-13T15:28:50.300 回答
2

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

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

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

于 2009-05-13T16:45:11.237 回答
1

在 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。

于 2013-03-05T10:52:29.640 回答
0

尝试这个:

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();
            }
        }
    }
}
于 2018-08-30T06:43:40.560 回答