fabriciols fabriciols - 5 months ago 114
Java Question

CDATA element in WSDL client

I'm doing a WSDL client and want to know how I can set an XML element to be CDATA.

I'm using the

wsimport
to generate the source code, and the CDATA element is part of the request XML.
This is the XML class of the request:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "dataRequest" })
@XmlRootElement(name = "ProcessTransaction")
public class ProcessTransaction {

protected String dataRequest;

public String getDataRequest() {
return dataRequest;
}

public void setDataRequest(String value) {
this.dataRequest = value;
}
}


I've already tried the @XmlAdapter, but it changes nothing on the output...

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class AdaptorCDATA extends XmlAdapter<String, String> {

@Override
public String marshal(String arg0) throws Exception {
return "<![CDATA[" + arg0 + "]]>";
}

@Override
public String unmarshal(String arg0) throws Exception {
return arg0;
}
}


In the XML class:

@XmlJavaTypeAdapter(value=AdaptorCDATA.class)
protected String dataRequest;


I tried to debug, but it never steps on the
AdaptorCDATA
function.

The
wsimport
version is
2.2.9
and the
jaxb-api
version is
2.1
.

Answer

So, as @user1516873 suggested, i moved the code to cxf, and with this, is working well. Now i'm using the "wsdl2java" to generate the code, and the jars from cxf on my project.

What is different in the code:

CdataInterceptor

import javax.xml.stream.XMLStreamWriter;

import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class CdataInterceptor extends AbstractPhaseInterceptor<Message> {

    public CdataInterceptor() {
        super(Phase.MARSHAL);
    }

    public void handleMessage(Message message) {
        message.put("disable.outputstream.optimization", Boolean.TRUE);
        XMLStreamWriter writer = (XMLStreamWriter) message.getContent(XMLStreamWriter.class);
        if (writer != null && !(writer instanceof CDataContentWriter)) {
            message.setContent(XMLStreamWriter.class, new CDataContentWriter(writer));
        }
    }

    public void handleFault(Message messageParam) {
        System.out.println(messageParam);
    }
}

CDataContentWriter

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;

public class CDataContentWriter extends DelegatingXMLStreamWriter {

    public CDataContentWriter(XMLStreamWriter writer) {
        super(writer);
    }

    public void writeCharacters(String text) throws XMLStreamException {
        boolean useCData = text.contains("RequestGeneric");
        if (useCData) {
            super.writeCData(text);
        } else {
            super.writeCharacters(text);
        }
    }

    // optional 
    public void writeStartElement(String prefix, String local, String uri) throws XMLStreamException {
        super.writeStartElement(prefix, local, uri);
    }
}

Using the Writer and the Interceptor:

MyService wcf = new MyService(url, qName);
IMyService a = wcf.getBasicHttpBinding();

Client cxfClient = ClientProxy.getClient(a);
CdataInterceptor myInterceptor = new CdataInterceptor();
cxfClient.getInInterceptors().add(myInterceptor);
cxfClient.getOutInterceptors().add(myInterceptor);

And it works perfect!

Comments