Java Jackson XML:如何将空/空集合序列化为空节点
我使用的是Jackson XML 2.8.9,不幸的是,我找不到任何方法将空/空集合序列化为空节点 负责序列化为XML的方法:Java Jackson XML:如何将空/空集合序列化为空节点,java,jackson-dataformat-xml,Java,Jackson Dataformat Xml,我使用的是Jackson XML 2.8.9,不幸的是,我找不到任何方法将空/空集合序列化为空节点 负责序列化为XML的方法: protected byte[] toXml(final Collection<ReportView> reports) throws IOException { final XmlMapper mapper = new XmlMapper(); // place for code which will solve my problem
protected byte[] toXml(final Collection<ReportView> reports) throws IOException
{
final XmlMapper mapper = new XmlMapper();
// place for code which will solve my problem
return mapper.writerWithDefaultPrettyPrinter().withRootName("report").writeValueAsBytes(reports);
}
final XmlSerializerProvider provider = new XmlSerializerProvider(new XmlRootNameLookup());
provider.setNullValueSerializer(new JsonSerializer<Object>()
{
@Override
public void serialize(final Object value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException
{
jgen.writeString("");
}
});
mapper.setSerializerProvider(provider);
@Test
public void testToXml() throws IOException
{
final Map<String, Object> payload = new LinkedHashMap<>();
payload.put("amp", "&");
payload.put("empty", Collections.emptyList());
final Date date = new Date();
final ReportView reportView = new ReportView(payload, date, "system");
// when
final byte[] xmlBytes = reportService.toXml(Arrays.asList(reportView));
// then
final StringBuilder expected = new StringBuilder();
expected.append("<report>");
expected.append(" <item>");
expected.append(" <payload>");
expected.append(" <amp>&</amp>");
expected.append(" <empty></empty>");
expected.append(" </payload>");
expected.append(" <timestamp>" + date.getTime() + "</timestamp>");
expected.append(" <changingUser>system</changingUser>");
expected.append(" </item>");
expected.append("</report>");
final String xmlText = new String(xmlBytes).replace("\n", "").replace("\r", "");
assertThat(xmlText).isEqualTo(expected.toString());
}
我准备了一个带有示例代码的存储库:
编辑: 我扩展了test
toXml
方法,并进行了一些代码清理
我还尝试创建一个基于模块
和序列化修改器
的解决方案。不幸的是,两人都以失败告终。我在jackson dataformat xml
backlog中创建了一个问题:
编辑:
我得到了一个如何解决异常问题的提示(请参阅),但它仍然不能解决缺少
空/空值的问题。我需要解决同样的问题,下面是我如何使它工作的:
首先,我创建一个序列化程序,将null序列化为空字符串:
公共类NullAsEmptyStringSerializer扩展JsonSerializer{
静态最终JsonSerializer实例=新的NullAsEmptyStringSerializer();
私有静态最终字符串为空_String=“”;
私有最终StringSerializer StringSerializer=新StringSerializer();
@凌驾
public void序列化(对象值、JsonGenerator gen、SerializerProvider序列化器)
抛出IOException{
序列化(空字符串,gen,序列化器);
}
}
然后,我创建一个序列化程序修饰符,用我的新序列化程序覆盖bean属性的空序列化程序:
公共类NullToEmptyPropertySerializerModifier扩展了BeanSerializerModifier{
@凌驾
公共列表changeProperties(SerializationConfig配置,
Bean描述Bean描述,列出Bean属性){
for(beanProperty编写器beanProperty:beanProperties){
assignNullSerializer(NullAsEmptyStringSerializer.INSTANCE);
}
返回Bean属性;
}
}
最后,我将xml映射器配置为使用我的修饰符:
NullToEmptyPropertySerializerModifier修饰符=新的NullToEmptyPropertySerializerModifier();
SerializerFactory SerializerFactory=BeanSerializerFactory.instance.withSerializerModifier(修饰符);
XmlMapper XmlMapper=新的XmlMapper();
setSerializerFactory(serializerFactory);
尝试查看它是否适用于字符串和对象(Person
和Dog
是虚拟数据持有者对象):
提供以下输出:
utku29
为什么需要发出
?我使用XSLT技术将这些XML文件转换为人类可读的形式。我想打印字段“空”:没有内容,而不是什么都没有。这两个信息完全不同:empty/null
vs不存在
。我检查了它,它不起作用。建议的代码将null
序列化为具有空值的元素,而不是空元素(
← 空元素,
← 元素(具有空值)。它还影响空列表和数组的序列化-它们不再序列化为空元素。以下是用于测试的项目:
mapper.configure(FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL, false);
@Test
public void testToXml() throws IOException
{
final Map<String, Object> payload = new LinkedHashMap<>();
payload.put("amp", "&");
payload.put("empty", Collections.emptyList());
final Date date = new Date();
final ReportView reportView = new ReportView(payload, date, "system");
// when
final byte[] xmlBytes = reportService.toXml(Arrays.asList(reportView));
// then
final StringBuilder expected = new StringBuilder();
expected.append("<report>");
expected.append(" <item>");
expected.append(" <payload>");
expected.append(" <amp>&</amp>");
expected.append(" <empty></empty>");
expected.append(" </payload>");
expected.append(" <timestamp>" + date.getTime() + "</timestamp>");
expected.append(" <changingUser>system</changingUser>");
expected.append(" </item>");
expected.append("</report>");
final String xmlText = new String(xmlBytes).replace("\n", "").replace("\r", "");
assertThat(xmlText).isEqualTo(expected.toString());
}
public class ReportView {
private final Map<String, Object> payload;
private final Date timestamp;
private final String changingUser;
public ReportView(Map<String, Object> payload, Date timestamp, String changingUser) {
this.payload = payload;
this.timestamp= timestamp;
this.changingUser = changingUser;
}
public String getChangingUser() {
return changingUser;
}
public Date getTimestamp() {
return timestamp;
}
public Map<String, Object> getPayload() {
return payload;
}
}
Dog dog = new Dog("bobby");
Person person = new Person("utku", null, 29, null);
String serialized = xmlMapper.writeValueAsString(person);
System.out.println(serialized);