Apache CXF wsdl2java客户端 - CDATA中的字符串而不是转义字符

时间:2013-06-12 15:06:52

标签: escaping cxf special-characters cdata wsdl2java

我使用Apache CXF wsdl2java工具编写了webservice客户端。它工作正常,但在一种方法中,我必须发送包含特殊字符的字符串。生成的客户端使用转义字符。我不要那个。我想把字符串放在"< [!CDATA []]>"块。我可以添加"< [!CDATA []]>"在代码中手动 - 这不会是一个问题,但我不知道如何关闭cachracter逃避。有这样的问题吗?如何以最简单的方式解决它?

[编辑]:Daniel Kulp回答后我做了这个:

我写了拦截器:

public class CDATAInterceptor extends AbstractPhaseInterceptor<Message> {

    public CDATAInterceptor(String phase) {
        super(phase);
    }

    public void handleMessage(Message message) {
        XMLStreamWriter writer = (XMLStreamWriter) message.getContent(XMLStreamWriter.class);
        if (writer != null && !(writer instanceof MyXmlWriter)) {
            message.setContent(XMLStreamWriter.class, new MyXmlWriter(writer));
        }
    }
}

我已将它添加到任何可能的阶段(以防万一 - 我可能应该放入MARSHAL或PRE_MARSHAL)。以下是我如何添加拦截器的代码:

MyService service = new MyService(new URL(http://my_url_adress?wsdl));
proxy = service.getMyServiceSoap12();
Client client = ClientProxy.getClient(proxy);

client.getOutInterceptors().add(new CDATAInterceptor(Phase.INVOKE));
client.getOutInterceptors().add(new CDATAInterceptor(Phase.MARSHAL));
client.getOutInterceptors().add(new CDATAInterceptor(Phase.MARSHAL_ENDING));
client.getOutInterceptors().add(new CDATAInterceptor(Phase.POST_INVOKE));
client.getOutInterceptors().add(new CDATAInterceptor(Phase.POST_LOGICAL));
client.getOutInterceptors().add(new CDATAInterceptor(Phase.POST_LOGICAL_ENDING));
...

这是MyXmlWriter类代码:

public class MyXmlWriter implements XMLStreamWriter {

    protected XMLStreamWriter originalXmlWriter;

    public MyXmlWriter(XMLStreamWriter originalXmlWriter) {
        this.originalXmlWriter = originalXmlWriter;
    }

    public void writeStartElement(String localName) throws XMLStreamException {
        this.originalXmlWriter.writeStartElement(localName);
    }

    public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
        this.originalXmlWriter.writeStartElement(namespaceURI, localName);
    }

    public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
        this.originalXmlWriter.writeStartElement(prefix, localName, namespaceURI);
    }

    public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
        this.originalXmlWriter.writeEmptyElement(namespaceURI, localName);
    }

    public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
        this.originalXmlWriter.writeEmptyElement(prefix, localName, namespaceURI);
    }

    public void writeEmptyElement(String localName) throws XMLStreamException {
        this.originalXmlWriter.writeEmptyElement(localName);
    }

    public void writeEndElement() throws XMLStreamException {
        this.originalXmlWriter.writeEndElement();
    }

    public void writeEndDocument() throws XMLStreamException {
        this.originalXmlWriter.writeEndDocument();
    }

    public void close() throws XMLStreamException {
        this.originalXmlWriter.close();
    }

    public void flush() throws XMLStreamException {
        this.originalXmlWriter.flush();
    }

    public void writeAttribute(String localName, String value) throws XMLStreamException {
        this.originalXmlWriter.writeAttribute(localName, value);
    }

    public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
        this.originalXmlWriter.writeAttribute(prefix, namespaceURI, localName, value);
    }

    public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
        this.originalXmlWriter.writeAttribute(namespaceURI, localName, value);
    }

    public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
        this.originalXmlWriter.writeNamespace(prefix, namespaceURI);
    }

    public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
        this.originalXmlWriter.writeDefaultNamespace(namespaceURI);
    }

    public void writeComment(String data) throws XMLStreamException {
        this.originalXmlWriter.writeComment(data);
    }

    public void writeProcessingInstruction(String target) throws XMLStreamException {
        this.originalXmlWriter.writeProcessingInstruction(target);
    }

    public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
        this.originalXmlWriter.writeProcessingInstruction(target, data);
    }

    public void writeCData(String data) throws XMLStreamException {
        this.originalXmlWriter.writeCData(data);
    }

    public void writeDTD(String dtd) throws XMLStreamException {
        this.originalXmlWriter.writeDTD(dtd);
    }

    public void writeEntityRef(String name) throws XMLStreamException {
        this.originalXmlWriter.writeEntityRef(name);
    }

    public void writeStartDocument() throws XMLStreamException {
        this.originalXmlWriter.writeStartDocument();
    }

    public void writeStartDocument(String version) throws XMLStreamException {
        this.originalXmlWriter.writeStartDocument(version);
    }

    public void writeStartDocument(String encoding, String version) throws XMLStreamException {
        this.originalXmlWriter.writeStartDocument(encoding, version);
    }

    public void writeCharacters(String text) throws XMLStreamException {
        this.originalXmlWriter.writeCData(text);
    }

    public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
        this.originalXmlWriter.writeCData(String.copyValueOf(text, len, len));
    }

    public String getPrefix(String uri) throws XMLStreamException {
        return this.originalXmlWriter.getPrefix(uri);
    }

    public void setPrefix(String prefix, String uri) throws XMLStreamException {
        this.originalXmlWriter.setPrefix(prefix, uri);
    }

    public void setDefaultNamespace(String uri) throws XMLStreamException {
        this.originalXmlWriter.setDefaultNamespace(uri);
    }

    public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
        this.originalXmlWriter.setNamespaceContext(context);
    }

    public NamespaceContext getNamespaceContext() {
        return this.originalXmlWriter.getNamespaceContext();
    }

    public Object getProperty(String name) throws IllegalArgumentException {
        return this.originalXmlWriter.getProperty(name);
    }
}

这不起作用。我一直在调查它是如何工作的,我注意到MyXmlWriter.writeCharacters(...)方法几乎从未使用过。输出消息仍然具有转义字符,而不是在CDATA内。

[EDIT2]: 我刚发现我必须添加一行:

message.put("disable.outputstream.optimization", Boolean.TRUE); 

来源:http://cxf.547215.n5.nabble.com/CXF-jaxb-send-string-as-CData-td5524523.html

1 个答案:

答案 0 :(得分:4)

唯一的方法是编写一个拦截器,它将从消息中获取XMLStreamWriter,用一个新的XMLStreamWriter包装它,它将覆盖字符方法并调用委托cdata方法而不是字符。