使用Jackson XmlMapper进行序列化时添加DTD

当我序列化我的POJO时,一切都按预期工作。 我得到这样的东西:

  ...  

收件人(Google Search Appliance)似乎期望XML包含这样的DTD:

    ...  

我怎样才能做到这一点?

根据其他答案,遗憾的是没有办法以简单的方式实现这一点。

对于长期而言可能有用的一件事是提交添加此类function的请求 – 例如,通过特定ObjectWriter XML的ObjectWriter公开它听起来像是一个合理的function。

我通常鄙视jackson提出的“编写自定义序列化器”问题的答案,因为通常会有一种更简单,更清晰的方法。 不幸的是,我不知道一种更好的方法来实现向序列化输出添加元数据,而不是自定义序列化器。

希望有人回答一个更简单的解决方案,但这应该实现你想要实现的目标。

创建一个模块来容纳自定义序列化程序

 public class GsaFeedModule extends SimpleModule { private static final String NAME = "GsaFeedModule"; public GsaFeedModule() { super(NAME); addSerializer(GsaFeed.class, new GsaFeedSerializer()); } public static class GsaFeedSerializer extends JsonSerializer { @Override public void serialize(GsaFeed gsaFeed, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeRaw(""); jsonGenerator.writeRaw(""); jsonGenerator.writeStartObject(); // write fields jsonGenerator.writeEndObject(); } } } 

注册模块

 XmlMapper xm = new XmlMapper(); xm.registerModule(new GsaFeedModule()); 

似乎没有一种优雅的方式来设置DTD。 除了实现自定义序列化程序之外,您还可以考虑重写XmlSerializerProvider以在XML生成器初始化之后写入DTD字符串写入。 这是一个例子:

 public class JacksonXmlDTD { private static class DtdXmlSerializerProvider extends XmlSerializerProvider { private final String dtd; public DtdXmlSerializerProvider( final XmlSerializerProvider src, final SerializationConfig config, final SerializerFactory jsf, final String dtd) { super(src, config, jsf); this.dtd = dtd; } @Override protected void _initWithRootName(final ToXmlGenerator xgen, final QName rootName) throws IOException { super._initWithRootName(xgen, rootName); try { xgen.getStaxWriter().writeDTD(dtd); } catch (final XMLStreamException e) { StaxUtil.throwXmlAsIOException(e); } } @Override public DefaultSerializerProvider createInstance( final SerializationConfig config, final SerializerFactory jsf) { return new DtdXmlSerializerProvider(this, config, jsf, dtd); } } public static void main(String[] args) throws JsonProcessingException { final XmlMapper xmlMapper = new XmlMapper(); xmlMapper.enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION); final String dtd = ""; final DtdXmlSerializerProvider serializerProvider = new DtdXmlSerializerProvider( (XmlSerializerProvider) xmlMapper.getSerializerProvider(), xmlMapper.getSerializationConfig(), xmlMapper.getSerializerFactory(), dtd); xmlMapper.setSerializerProvider(serializerProvider); final Map map = new HashMap<>(); map.put("object", "value"); System.out.println(xmlMapper.writeValueAsString(map)); } } 

输出:

 value