2017-04-05 100 views
0

我正在寫一個SOAP客戶端,針對產生不符合規格的錯誤的服務器。具體來說,故障原因(spec)中的Text元素中缺少lang屬性。我使用的是Spring WS 2.4.0。有沒有辦法攔截響應並在將屬性解析爲SaajSoapMessage之前注入該屬性?我嘗試創建一個ClientInterceptor,但是xml在它到達攔截器時已經被解析。我需要創建自己的MessageFactory嗎?處理格式錯誤的soap故障

回答

1

我已經在this answerthis answer的幫助下解決了這個問題。

當我實例化我WebServiceGatewaySupport,我添加一個ClientInterceptor其中I配置的handleFault()方法:

@Override 
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException { 
    LOGGER.debug("intercepted a fault."); 
    TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
    WebServiceMessage response = messageContext.getResponse(); 
    Source source = response.getPayloadSource(); 
    StreamResult streamResult = new StreamResult(new StringWriter()); 

    try { 
     Transformer displayTransformer = transformerFactory.newTransformer(); 
     displayTransformer.transform(source, streamResult); 
     LOGGER.debug("\t>> initial response\n" + streamResult.getWriter().toString()); 

     StreamSource xslSource = new StreamSource(new File(
       FaultInterceptor.class.getResource("/SoapFaultFix.xsl").getFile() 
     )); 
     Transformer modifyingTransformer = transformerFactory.newTransformer(xslSource); 
     modifyingTransformer.transform(source, response.getPayloadResult()); 

    } catch (TransformerException e) { 
     e.printStackTrace(); 
    } 

    return true; 
} 

這簡單地取源XML並運行它通過一個XSL轉換。從identity transformation開始非常重要,因此您不會丟失內容。然後我添加了屬性和值,然後刪除了現有的值。我SoapFaultFix.xsl是這樣的:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" 
> 
    <xsl:template match="/ | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="//soapenv:Fault/soapenv:Reason/soapenv:Text"> 
     <soapenv:Text> 
      <xsl:attribute name="xml:lang">en</xsl:attribute> 
      <xsl:value-of select="."/> 
     </soapenv:Text> 
    </xsl:template> 
</xsl:stylesheet> 

我喜歡這種做法,因爲我發現鑽入DOM是艱鉅的純Java的,我可以很容易地擴展了xsl做出其他改變。