2017-04-05 3 views
0

Ich schreibe einen SOAP-Client gegen einen Server, der einen Fehler erzeugt, der nicht der Spezifikation entspricht. Insbesondere fehlt das lang Attribut in dem Element Text im Fehlergrund (spec). Ich benutze Spring WS 2.4.0. Gibt es eine Möglichkeit, die Antwort abzufangen und das Attribut zu injizieren, bevor es in eine SaajSoapMessage geparst wird? Ich habe versucht, einen ClientInterceptor zu erstellen, aber das XML wurde bereits analysiert, als es den Interceptor trifft. Müsste ich meine eigene MessageFactory erstellen?Umgang mit einem fehlerhaften Soap-Fehler

Antwort

1

Ich habe dies mit Hilfe von this answer und this answer gelöst.

Wenn ich meine WebServiceGatewaySupport instanziiert, fügte ich eine ClientInterceptor, wo ich die handleFault() Methode konfiguriert:

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

Dies nimmt einfach die XML-Quell und führt es durch eine XSL-Transformation. Es ist wichtig, mit einem identity transformation zu beginnen, damit Sie Inhalt nicht verlieren. Ich fügte dann das Attribut und den Wert hinzu und ließ dann den vorhandenen Wert fallen. Meine SoapFaultFix.xsl sah wie folgt aus:

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

ich diesen Ansatz gemocht, weil ich Bohren gefunden in die DOM beschwerliche mit reinem Java war, und ich konnte die xsl machen andere Änderungen leicht erweitern.

Verwandte Themen