Java 如何使用Jackson将xml的一部分封装在CDATA标记中

Java 如何使用Jackson将xml的一部分封装在CDATA标记中,java,xml-serialization,jackson,Java,Xml Serialization,Jackson,我有以下java对象 class MyXmlObject{ @JsonProperty private InnerObject innerObject; @JsonProperty private String someOtherProperty; } 当我使用 public String getXmlObjectAsXML(MyXmlObject myXmlObject){ JacksonXmlModule module = new JacksonXm

我有以下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标记中


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

我不知道有任何选项可以让输出使用CDATA节


但是为什么需要使用CDATA分区呢?在XML中,CDATA在语义上与常规文本部分没有区别。它只是为了方便手工编辑而存在。

我最后只是放了一个占位符,将两个对象都标记出来,然后手动操作字符串。。。不干净不漂亮,但它工作了。

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

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

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

在工厂中,除了使用纯传递函数包装所有其他方法外,每个createXMLStreamWriter()函数都需要类似的内容(共有4个):

其中
f
是类中构造的
OutputFactoryImpl

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);
}
完整的代码可以在上面的要点中看到


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

自2.5版起就有
@jacksonxmlcata

@jacksonxmlcata
允许指定在CData标记中序列化属性的值


我们的esb需要它。。。我个人永远不会这么做。不确定如何做到这一点——理论上,您可能能够将
XMLOutputFactory
子类化,以生成hi-jacks
writeCharacters()
调用
writeCData
XMLStreamWriter
实例。Woodstox有一些功能来帮助委托调用,这可能会起作用。但我想不出默认特性;相反(“将所有文本输出为字符,即使指示使用CDATA”)。哦,您也可以为Jackson XML模块提交此功能请求。在那里实施其实很容易;调用
writeCData()
而不是
writeCharacters()
。只要在所有文本编写中使用它就可以了。比我希望的要复杂得多,但比我对实际物理文本的破解要干净得多。同意,我希望Jackson代码更灵活一点。因为它们提供了重写工厂类的能力,我不明白为什么所有相关的类都是final。如果CData本机支持注释,那就更好了。哇,我不需要再这样做了,但知道这一点真的很好
public void init() {
    XmlFactory factory = new XmlFactory(new InputFactoryImpl(),
            new CDataXmlOutputFactoryImpl());
    xmlMapper = new XmlMapper(factory);
    xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
}