2016-06-20 19 views
8

Sto facendo un client WSDL e voglio sapere come posso impostare un elemento XML come CDATA.Elemento CDATA nel client WSDL

Sto utilizzando il wsimport per generare il codice sorgente e l'elemento CDATA è parte della richiesta XML. Questa è la classe XML della richiesta:

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

Ho già provato la @XmlAdapter, ma non cambia nulla sull'uscita ...

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

Nella classe XML:

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

Ho provato a eseguire il debug, ma non ha mai eseguito la funzione AdaptorCDATA.

La versione wsimport è 2.2.9 e la versione jaxb-api è 2.1.

+0

Perché ne hai bisogno? Perché vuoi scrivere xml-data sull'elemento? Questo dovrebbe funzionare immediatamente. Abbiamo una stringa di dati xml, imposta questo valore come valore nell'elemento corrispondente e quindi la magia di JAXB avvolge un CDATA tutto intorno al marshalling. – Frank

+0

Mi serve perché, quando imposto "dataRequest" con una stringa CDATA, viene completamente sfuggito. – fabriciols

+0

OK, ho appena provato il tuo AdaptorCDATA con un membro String arbitrario di una delle nostre classi e si comporta bene nel metodo 'marshall()'. Guardando la tua domanda vedo che hai uno snippet in cui hai l'annotazione '@ XmlJavaTypeAdapter' ma non nella classe' ProcessTransaction' dove dovrebbe essere. Se ce l'hai, ma il punto di interruzione non viene ancora raggiunto, forse devi ricostruire e aggiornare prima di avviare il client? – Frank

risposta

1

Quindi, come suggerito da @user1516873, ho spostato il codice in cxf e, con questo, funziona bene. Ora sto usando il "wsdl2java" per generare il codice e i jar da cxf sul mio progetto.

Ciò che è diverso nel codice:

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

Utilizzando lo scrittore e l'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); 

E funziona perfettamente!