gpt4 book ai didi

java - jackson XML : how to serialize empty/null collections as empty node

转载 作者:太空宇宙 更新时间:2023-11-04 11:10:57 25 4
gpt4 key购买 nike

我正在使用 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
return mapper.writerWithDefaultPrettyPrinter().withRootName("report").writeValueAsBytes(reports);
}

我尝试使用:

  • 序列化包含:

    mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
  • 序列化提供程序:

    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);
  • Jackson 2.9.0 EMPTY_ELEMENT_AS_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;</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());
}

ReportView 类:

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;
}
}

我准备了一个包含示例代码的存储库:https://github.com/agabrys/bugs-reports/tree/master/jackson-xml/empty-elements-serialization

<小时/>

编辑:

我扩展了测试 toXml 方法并进行了一些代码清理。

我还尝试创建一个基于ModuleSerializerModifier的解决方案。可惜两者都以失败告终。我在 jackson-dataformat-xml backlog 中创建了一个问题:

<小时/>

编辑:

我得到了如何解决异常问题的提示(请参阅 NPE after overriding map serializer with custom implementation (XmlBeanSerializerModifier.modifyMapSerializer) ),但它仍然无法解决缺少 empty/null 值的问题。

最佳答案

我需要解决同样的问题,以下是我的解决方法:

首先,我创建一个序列化器,将 null 序列化为空字符串:

public class NullAsEmptyStringSerializer extends JsonSerializer<Object> {

static final JsonSerializer<Object> INSTANCE = new NullAsEmptyStringSerializer();

private static final String EMPTY_STRING = "";
private final StringSerializer stringSerializer = new StringSerializer();

@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
stringSerializer.serialize(EMPTY_STRING, gen, serializers);
}
}

然后我创建一个序列化器修饰符,它用我的新序列化器覆盖 bean 属性的 null 序列化器:

public class NullToEmptyPropertySerializerModifier extends BeanSerializerModifier {

@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
for (BeanPropertyWriter beanProperty : beanProperties) {
beanProperty.assignNullSerializer(NullAsEmptyStringSerializer.INSTANCE);
}

return beanProperties;
}
}

最后,我配置 xml 映射器以使用我的修饰符:

NullToEmptyPropertySerializerModifier modifier = new NullToEmptyPropertySerializerModifier();
SerializerFactory serializerFactory = BeanSerializerFactory.instance.withSerializerModifier(modifier);
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setSerializerFactory(serializerFactory);

尝试查看它是否适用于字符串和对象(PersonDog 是虚拟数据持有者对象):

Dog dog = new Dog("bobby");
Person person = new Person("utku", null, 29, null);
String serialized = xmlMapper.writeValueAsString(person);
System.out.println(serialized);

给出以下输出:

<Person><name>utku</name><address></address><age>29</age><dog></dog></Person>

关于java - jackson XML : how to serialize empty/null collections as empty node,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46001938/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com