2017-04-12 5 views
1

私はapache cxfエンドポイントでエスケープされていないxml文字列を返す必要があります。私は私のコードのセクションを貼り付け下に、現在のXML文字列が返されると、所望のXML文字列:Unescape Xml Apache Cxfエンドポイントでの特殊文字

@WebService(endpointInterface = "net.system.soapservice.result.ResultMgrPortType", serviceName = "ResultMgrPortType") 
public class ResultServiceImpl implements ResultMgrPortType { 

@Override 
public String genericAPIResult(String resultMsg) { 

    Map<String, String> processedResultMsg = DataFormatUtil.parseResultMsg(resultMsg); 

    String response = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" 
      + "<soapenv:Body>" 
      + "<req:ResponseMsg" 
      + " xmlns:req=\"http://api-v1.gen.mm.vodafone.com/mminterface/request\"><![CDATA[<?xml" 
      + " version=\"1.0\"" 
      + "encoding=\"UTF-8\"?><response" 
      + " xmlns=\"http://api-" 
      + "v1.gen.mm.vodafone.com/mminterface/response\">" 
      + "<ResponseCode>"+processedResultMsg.get("ResultCode")+"</ResponseCode>" 
      + "<ConversationID>"+processedResultMsg.get("ConversationID")+"</ConversationID>" 
      + "<ResponseDesc>Service result processed successfully.</ResponseDesc>" 
      + "<OriginatorConversationID>"+processedResultMsg.get("OriginatorConversationID")+"</OriginatorConversationID>" 
      + "<ServiceStatus>0</ServiceStatus>" 
      + "</response>]]></req:ResponseMsg>" 
      + "</soapenv:Body>" 
      + "</soapenv:Envelope>"; 
    return response; 
} 

}

私のログに見られるように、上記エンドポイントからのXML応答:

ID: 4 
Response-Code: 200 
Encoding: UTF-8 
Content-Type: text/xml 
Headers: {} 
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ResponseMsg xmlns="http://api-v1.gen.mm.vodafone.com/mminterface/result">&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt; 
&lt;soapenv:Body&gt; 
&lt;req:ResponseMsg 
xmlns:req="http://api-v1.gen.mm.vodafone.com/mminterface/request"&gt;&lt;![CDATA[&lt;?xml 
version="1.0" 
encoding="UTF-8"?&gt;&lt;response 
xmlns="http://api- 
v1.gen.mm.vodafone.com/mminterface/response"&gt;&lt;ResponseCode&gt;0&lt;/ResponseCode&gt;&lt;ConversationID&gt;AG_20170411_000059047aba809d6631&lt;/ConversationID&gt;&lt;ResponseDesc&gt;Service result processed successfully.&lt;/ResponseDesc&gt;&lt;OriginatorConversationID&gt;902004_fhltd_60575.0&lt;/OriginatorConversationID&gt;&lt;ServiceStatus&gt;0&lt;/ServiceStatus&gt;&lt;/response&gt;]]&gt;&lt;/req:ResponseMsg&gt; 
&lt;/soapenv:Body&gt; 
&lt;/soapenv:Envelope&gt;</ResponseMsg></soap:Body></soap:Envelope> 
-------------------------------------- 

クライアントが期待するのxml:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
     <ResponseMsg xmlns="http://api-v1.gen.mm.vodafone.com/mminterface/result"> 
     <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
      <soapenv:Body> 
       <req:ResponseMsg xmlns:req="http://api-v1.gen.mm.vodafone.com/mminterface/request"><![CDATA[<?xml version="1.0"encoding="UTF-8"?><response xmlns="http://api-v1.gen.mm.vodafone.com/mminterface/response"><ResponseCode>0</ResponseCode><ConversationID>AG_20170406_00004ddc3d70f6ba93f0</ConversationID><ResponseDesc>Service result processed successfully.</ResponseDesc><OriginatorConversationID>902004_fhltd_94802.0</OriginatorConversationID><ServiceStatus>0</ServiceStatus></response>]]></req:ResponseMsg> 
      </soapenv:Body> 
     </soapenv:Envelope> 
     </ResponseMsg> 
    </soap:Body> 
</soap:Envelope> 

NB:レスポンスがを持つべきではありませんおよび&gtapache-cxf-services.xmlファイルに設定を追加するか、この動作を変更するためのインターセプタを作成する必要があります。あなたの時間と労力に事前に感謝します。

答えて

1

ここに私自身の質問に答えます。解決策は、cxfのjaxbにCDATAのレスポンス文字列をエンコードするためのインターセプタを作成することです。だから私は、即時応答からCDATAを削除(これは今インターセプタによって処理されなければならない)、そして得られた応答は次のようになります。そして、PRE_STREAM段階でバックCDATAを追加するインターセプタを作成

String response = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" 
      + "<soapenv:Body>" 
      + "<req:ResponseMsg" 
      + " xmlns:req=\"http://api-v1.gen.mm.vodafone.com/mminterface/request\"><?xml" 
      + " version=\"1.0\"" 
      + "encoding=\"UTF-8\"?><response" 
      + " xmlns=\"http://api-" 
      + "v1.gen.mm.vodafone.com/mminterface/response\">" 
      + "<ResponseCode>"+processedResultMsg.get("ResultCode")+"</ResponseCode>" 
      + "<ConversationID>"+processedResultMsg.get("ConversationID")+"</ConversationID>" 
      + "<ResponseDesc>Service result processed successfully.</ResponseDesc>" 
      + "<OriginatorConversationID>"+processedResultMsg.get("OriginatorConversationID")+"</OriginatorConversationID>" 
      + "<ServiceStatus>0</ServiceStatus>" 
      + "</response></req:ResponseMsg>" 
      + "</soapenv:Body>" 
      + "</soapenv:Envelope>"; 

を:

import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.XMLStreamWriter; 
import org.apache.cxf.staxutils.DelegatingXMLStreamWriter; 

public class CDataXMLStreamWriter extends DelegatingXMLStreamWriter { 

    private String currentElementName; 

    public CDataXMLStreamWriter(XMLStreamWriter del) { 
     super(del); 
    } 

    @Override 
    public void writeCharacters(String text) throws XMLStreamException { 
      System.out.println("WritingCData" + text); 
      super.writeCData(text); 
    } 

    private boolean checkIfCDATAneededForCurrentElement() { 
     if ("MessageBody".equals(currentElementName)) { 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public void writeStartElement(String prefix, String local, String uri) throws XMLStreamException { 
     currentElementName = local; 
     super.writeStartElement(prefix, local, uri); 
    } 
} 

アイデアは、XML文字列がCDAT内で送信されている場合ということです:CDataXMLStreamWriterに、以下に示すよう

import java.io.OutputStream; 
import javax.xml.stream.XMLStreamWriter; 
import org.apache.cxf.interceptor.AttachmentOutInterceptor; 
import org.apache.cxf.message.Message; 
import org.apache.cxf.phase.AbstractPhaseInterceptor; 
import org.apache.cxf.phase.Phase; 
import org.apache.cxf.staxutils.StaxUtils; 


public class CdataWriterInterceptor extends AbstractPhaseInterceptor<Message> { 

    public CdataWriterInterceptor() { 
     super(Phase.PRE_STREAM); 
     addAfter(AttachmentOutInterceptor.class.getName()); 
    } 

    @Override 
    public void handleMessage(Message message) { 
     System.out.println("############# CdataWriterInterceptor Executed #######################"); 
     message.put("disable.outputstream.optimization", Boolean.TRUE); 
     XMLStreamWriter writer 
       = StaxUtils.createXMLStreamWriter(message.getContent(OutputStream.class)); 
     message.setContent(XMLStreamWriter.class, new CDataXMLStreamWriter(writer)); 
    } 
} 

は最後にCDATAを追加しますセクションでは、cxf内部xmlパーサーによって解析されないため、特殊文字はエスケープされません。これは私のために働いて、私はそれが他の人のために働くことを願っています。詳細はこちらCXF jaxb send string as CData