2017-04-05 66 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做出其他改变。