2016-06-20 26 views
8

Ich mache einen WSDL-Client und möchte wissen, wie ich ein XML-Element als CDATA definieren kann.CDATA-Element im WSDL-Client

Ich verwende die wsimport, um den Quellcode zu generieren, und das CDATA-Element ist Teil der Anfrage XML. Dies ist die XML-Klasse der Anfrage:

@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; 
    } 
} 

ich versucht habe bereits die @XmlAdapter, aber es ändert nichts an dem Ausgang ...

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 der XML-Klasse:

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

Ich habe versucht zu debuggen, aber es tritt nie auf die AdaptorCDATA Funktion.

Die wsimport Version ist 2.2.9 und die jaxb-api Version ist 2.1.

+0

Warum brauchen Sie das? Weil Sie XML-Daten in das Element schreiben wollen? Dies sollte out-of-the-box funktionieren. Wir haben eine xml-data Zeichenfolge, setzen diese als Wert in dem entsprechenden Element und dann umschließt JAXBs Magie eine CDATA rundherum beim Marshalling. – Frank

+0

Ich brauche dies, weil, wenn ich die "DataRequest" mit einem CDATA-String festgelegt, es vollständig maskiert wird. – fabriciols

+0

OK, ich habe gerade Ihre AdaptorCDATA mit einem beliebigen String-Member einer unserer Klassen ausprobiert und es geht gut in die 'marshall()' -Methode. Wenn ich Ihre Frage ansehe, sehe ich, dass Sie einen Ausschnitt haben, in dem Sie die '@ XmlJavaTypeAdapter'-Annotation haben, aber nicht in der' ProcessTransaction'-Klasse, wo es sein sollte. Wenn Sie es dort haben, aber der Haltepunkt immer noch nicht getroffen wird, müssen Sie vielleicht neu aufbauen und aktualisieren, bevor Sie den Client starten? – Frank

Antwort

1

Also, wie @user1516873 vorgeschlagen, ich habe den Code nach CXF verschoben, und damit funktioniert gut. Jetzt benutze ich den "wsdl2java", um den Code zu generieren, und die Gläser von cxf auf meinem Projekt.

Was ist anders in dem 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); 
    } 
} 

Mit dem Writer und der 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); 

Und es funktioniert perfekt!