6

我有以下java对象

class MyXmlObject{
    @JsonProperty
    private InnerObject innerObject;
    @JsonProperty
    private String someOtherProperty;
}

当我使用

public String getXmlObjectAsXML(MyXmlObject myXmlObject){
    JacksonXmlModule module = new JacksonXmlModule();

    module.setDefaultUseWrapper(false);
    XmlMapper mapper = new XmlMapper(module);

    mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

    String response = "";

    response = mapper.writeValueAsString(myXmlObject);
    return response;
}

我希望将 InnerObject 类包装在 CDATA 标记中。

处理这种情况的正确方法是什么?

4

4 回答 4

13

@JacksonXmlCData2.5开始。https://github.com/FasterXML/jackson-dataformat-xml

@JacksonXmlCData允许指定要在 CData 标记内序列化属性的值。

于 2015-03-11T18:38:53.583 回答
3

我不知道使输出使用 CDATA 部分的任何选项。

但是为什么需要使用 CDATA 部分呢?在 XML CDATA 中,在语义上与常规文本部分没有区别。它仅作为手动编辑的便利物而存在。

于 2013-09-20T20:13:07.983 回答
3

我们有一个类似的用例。我们需要用 CDATA 包装的 XML 中的所有文本字段。这是我们需要实现的 API 的要求,我们在 API 中没有发言权。

为了解决这个问题,我们创建了@StaxMan 建议的实现,以覆盖 XMLOutputFactory 和 XMLStreamWriter 来劫持writeCharacters()和调用writeCData(),这似乎很有效。您可以在此处查看我们的确切代码(更改了包名称)的要点:

https://gist.github.com/jbcpollak/8312151

简而言之,我们创建了一个CDataXmlOutputFactoryImpl创建CDataXmlStreamWriter. 不幸的是,我们需要包装目标类,而不是使用继承,因为它们都是最终的。此外,要使用的确切编写器是可变的,因此包装是一个更安全的选择。

在工厂中,除了使用纯传递函数包装所有其他方法外,您还需要为每个 createXMLStreamWriter() 函数提供类似的东西(有 4 个):

public XMLStreamWriter createXMLStreamWriter(Writer w) 
    throws XMLStreamException
{

    return new CDataXmlStreamWriter(f.createXMLStreamWriter(w));
}

wherefOutputFactoryImpl类中构造的。

除了CDataXmlStreamWriter以下两个方法外,所有必要的函数都是 w 中方法的纯委托:

public void writeCharacters(char[] text, int start, int len) 
    throws XMLStreamException
{
    w.writeCharacters(text, start, len);
}

// All this code just to override this method
public void writeCharacters(String text) throws XMLStreamException
{

    w.writeCData(text);
}

这就是你需要做的所有事情。只需像这样使用您的新工厂:

public void init() {
    XmlFactory factory = new XmlFactory(new InputFactoryImpl(),
            new CDataXmlOutputFactoryImpl());
    xmlMapper = new XmlMapper(factory);
    xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
}

完整的代码可以在上面的 Gist 中看到。

如果您只需要包含在 CDATA 中的几个字段,我不确定此解决方案是否有效。为此,我认为您需要修改 ToXmlGenerator,以使其以某种方式了解您的模型(也许使用注释?),然后生成器会writeCData()在必要时调用。

于 2014-01-08T05:25:27.487 回答
0

最后我只是放了一个占位符,对两个对象进行编组,然后用手操纵琴弦……不干净也不漂亮,但它起作用了。

于 2013-09-24T18:38:48.613 回答