2016-06-20 1 views
8

WSDL 클라이언트를 수행하고 XML 요소를 CDATA로 설정하는 방법을 알고 싶습니다.WSDL 클라이언트의 CDATA 요소

나는 wsimport을 사용하여 소스 코드를 생성했으며 CDATA 요소는 요청 XML의 일부입니다. ... XML 클래스에서

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

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

나는 이미 @XmlAdapter을 시도했지만, 그것은 출력에 아무것도 변경되지 않습니다 :

이 요청의 XML 클래스입니다
@XmlJavaTypeAdapter(value=AdaptorCDATA.class) 
protected String dataRequest; 

디버그를 시도했지만 AdaptorCDATA 기능을 수행하지 않습니다.

버전은 2.2.9이고 jaxb-api 버전은 2.1입니다.

+0

왜 필요합니까? 요소에 xml-data를 쓰려고하기 때문에? 이것은 즉시 사용 가능해야합니다. 우리는 XML 데이터 문자열을 가지고 해당 요소에 값으로 설정 한 다음 JAXB의 마술은 마샬링 할 때 CDATA를 모두 둘러 쌉니다. – Frank

+0

CDATA 문자열을 사용하여 "dataRequest"를 설정하면 완전히 이스케이프 처리되므로이 작업이 필요합니다. – fabriciols

+0

좋아요, 저는 우리 클래스 중 하나의 임의의 String 멤버로 AdaptorCDATA를 시도해 보았습니다. 그리고 그것은'marshall()'-method에 잘 맞았습니다. 귀하의 질문을 보면'@ XmlJavaTypeAdapter'-Annotation이 있지만 'ProcessTransaction' 클래스가 아닌 곳에서 스 니펫을 가지고있는 것을 볼 수 있습니다. 거기에 중단 점이 여전히 나타나지 않으면 클라이언트를 시작하기 전에 다시 작성하고 새로 고쳐야합니다. – Frank

답변

1

따라서 @user1516873이 제안되었으므로 코드를 cxf로 옮겼습니다.이 코드는 잘 작동합니다. 이제 코드를 생성하기 위해 "wsdl2java"를 사용하고 프로젝트에서 cxf의 항아리를 사용합니다.

코드에서 다른 무엇 :

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

라이터와 인터셉터 사용

CdataInterceptor :

그리고 완벽하게 작동합니다!