我已經在this answer和this 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做出其他改變。