java-具有空字段的JAXB编组
这是一个非常简单的请求,但是我只是没有找到一种方法。
我基本上是想在JAXB中设置一个角色,该角色说,每当遇到null字段时,而不是在输出中忽略它,请将其设置为空值。 因此,对于班级:
@XMLRootElement
Class Foo {
Integer num;
Date date;
….
}
如果date字段为null,则将其编组到XML文件中时,我的输出中没有该元素。 我想做的是在输出中包含所有字段; 如果它们为空,则将它们替换为-说一个空白。 因此输出应为:
123
谢谢,
Jalpesh。
5个解决方案
40 votes
谢谢你们的回答。
克里斯·戴尔(Chris Dail)-我尝试了您的方法,但它并没有真正做到我想要的。 尽管为我的字段定义了默认值,JAXB仍然忽略了我的空值。
在Jersey论坛中有人将我指向文档第2.2.12.8节“无价值”之后,我确实迷失了答案。
基本上,我要做的就是将以下内容添加到我的字段中:
@XmlElement(nillable = true)
添加完这些内容后,JAXB将在将这些字段编组为XML时显示这些字段:
...
5
....
Jalpesh answered 2020-02-18T04:02:16Z
4 votes
但是,但是...但是,空字符串不是日期的有效词汇表示形式,因此您不能这样做。 也就是说,如果您生成的XML文档的日期字段值为空,则它将无法正确验证。
换句话说,如果您的date元素的minOccurs为1或更大,而不是nillable,那么您绝对必须具有(1个或多个)日期,该日期不能为空(或空白或其他非值)。
Chris Jester-Young answered 2020-02-18T04:02:41Z
2 votes
如其他答案所示,该答案无效,因为它不是有效日期。 我有一个类似的问题,我想专门处理(与相同)。 由于不能使用null,因此可以在JAXB中使用默认值机制。 如果未指定,则以下内容将为默认值。 您可以通过代码检测到此特殊日期并处理此异常情况。
@XmlElement(defaultValue="1970-01-01T00:00:00.0-00:00")
因此可以检测到并清空日期值,但是您不能使用null进行操作。
Chris Dail answered 2020-02-18T04:03:06Z
1 votes
在MOXy中,您可以指定jsonProvider必须如何完成JAXB的工作。
因此,在执行JAX-RS时,请在从Application派生的类中添加以下代码
我在Tomcat 7上使用了此代码,效果很好。 (eclipselink 2.4.1)
@ApplicationPath("/rest")
public class RestApplication extends Application
{
...
public Set< Object> getSingletons()
{
HashSet set = new HashSet(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,我也遇到了使用null值的相同问题。尚未检查,但可能的答案是在可能的情况下在应用程序服务器级别配置JAXB。
Jan Serneels answered 2020-02-18T04:03:40Z
0 votes
尝试这个:
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();
}
}
}
}
xudd answered 2020-02-18T04:04:04Z