2015-12-14 4 views
15

私の春のWebサービスクライアントはSoapFaultsをキャッチするために、このカスタムリゾルバがありますカスタムにSoapFaultリゾルバのトリガーが、たSOAPBodyににSoapFaultを見つけない

public class MySoapFaultResolver extends SoapFaultMessageResolver implements FaultMessageResolver 
{ 
    private static Logger logger = Logger.getLogger(MySoapFaultResolver.class); 

    @Override 
    public void resolveFault(WebServiceMessage wsm) throws IOException 
    { 
     logger.debug("entering"); 

//  SOAPMessage soapMessage = (SOAPMessage) wsm; cant cast to this 
     SoapMessage soapMessage = (SoapMessage) wsm; 

     if(soapMessage == null) { 
      logger.debug("soapMessage is null"); 
     } else { 
      logger.debug("soapMessage is not null"); 
      QName om_fc = soapMessage.getFaultCode(); 
      String om_frs = soapMessage.getFaultReason(); 
      logger.debug("om_fc:" + om_fc); 
      logger.debug("om_frs:" + om_frs); 
      if(soapMessage.getSoapBody() == null) { 
       logger.debug("soap body is null");    
      } else { 
       logger.debug("soap body is not null"); 
       SoapBody sb = soapMessage.getSoapBody(); 
       logger.debug(sb.toString()); // prints [email protected] 
       QName sb_name = sb.getName(); 
       logger.debug("sb_name:" + sb_name); 
       Iterator<QName> iter_attr_sb = sb.getAllAttributes(); 
       while(iter_attr_sb.hasNext()) { 
        QName qname = iter_attr_sb.next(); 
        String qname_valu = sb.getAttributeValue(qname); 
        logger.debug("attribute: " + qname + ":" + qname_valu); 
       } 
       if(sb.hasFault()) { 
        logger.debug("soap body has fault"); 
        SoapFault sff = sb.getFault(); 
        QName fc = sff.getFaultCode(); 
        String fsr = sff.getFaultStringOrReason(); 
        logger.debug("fc:" + fc); 
        logger.debug("fsr:" + fsr); 
        Iterator<QName> iter_attr = sff.getAllAttributes(); 
        while(iter_attr.hasNext()) { 
         QName qname = iter_attr.next(); 
         String qname_valu = sff.getAttributeValue(qname); 
         logger.debug("attribute: " + qname + ":" + qname_valu); 
        } 
        if(sff.getFaultDetail() == null) { 
         logger.debug("fault has no details"); 
        } else { 
         logger.debug("fault has details"); 
         SoapFaultDetail faultDetail = sff.getFaultDetail(); 
         Iterator<SoapFaultDetailElement> detailEntries = faultDetail.getDetailEntries(); 
         while(detailEntries.hasNext()) { 
          SoapFaultDetailElement detailElement = detailEntries.next(); 
          logger.debug("Found SoapFaultDetailElement name:" + detailElement.getName()); 
         } 
        } 
       } else { 
        logger.debug("soap body does not have fault");  
       } 
      } 
     } 
     logger.debug("exiting"); 

     SoapFaultClientException sfce = new SoapFaultClientException(soapMessage); 
     throw new IOException("cursesfoiledagain", sfce); 
    } 

たこの障害は、サービスから戻ってきたときに実行されます:

<soap:Envelope> 
    <soap:Body> 
    <soap:Fault> 
     <faultcode>soap:Server</faultcode> 
     <faultstring>Could not open connection; nested exception is org.hibernate.exception.GenericJDBCException: Could not open connection</faultstring> 
    </soap:Fault> 
    </soap:Body> 
</soap:Envelope> 

とログファイルにこれを書き込みます

MySoapFaultResolver-resolveFault] - entering 
MySoapFaultResolver-resolveFault] - soapMessage is not null 
MySoapFaultResolver-resolveFault] - om_fc:null 
MySoapFaultResolver-resolveFault] - om_frs:null 
MySoapFaultResolver-resolveFault] - soap body is not null 
MySoapFaultResolver-resolveFault] - [email protected] 
MySoapFaultResolver-resolveFault] - sb_name:{http://schemas.xmlsoap.org/soap/envelope/}Body 
MySoapFaultResolver-resolveFault] - soap body does not have fault 
MySoapFaultResolver-resolveFault] - exiting 

私はなぜcで困惑していますodeはSoapBody内でSoapFaultを見つけられません。誰かがこれについていくつかの光を当てることができますか?興味があります。 --appended-- また、私はこのエラーを投げWebサービスを所有する:

public class MyOutSoapFaultInterceptor extends AbstractSoapInterceptor 
{ 
    private static Logger logger = Logger.getLogger(MyOutSoapFaultInterceptor.class); 

    public MyOutSoapFaultInterceptor() 
    { 
     super(Phase.MARSHAL); 
    } 

    @Override 
    public void handleMessage(SoapMessage message) throws Fault 
    { 
     logger.debug("entering"); 

     Exception e = message.getContent(Exception.class); 
     if(e == null) { 
      logger.debug("e is null"); 
     } else { 
      logger.debug("e is not null"); 
      logger.debug("e.getCause:" + e.getCause()); 
      logger.debug("e.getMessage:" + e.getMessage()); 
      if(e instanceof Fault) { 
       logger.debug("e is instanceOf Fault"); 
       Fault f = (Fault) message.getContent(Fault.class); 
       SoapFault sf = SoapFault.createFault((Fault) e, message.getVersion()); 
       logger.debug("sf is not null"); 
       logger.debug("sf.getCause:" + sf.getCause()); 
       logger.debug("sf.getMessage:" + sf.getMessage()); 
       logger.debug("sf.getStatusCode:" + sf.getStatusCode()); 
       logger.debug("sf.getCode:" + sf.getCode()); 
       FormsEndpointFault newFault = new FormsEndpointFault(); 
       newFault.setCode(sf.getStatusCode()); 
       newFault.setMessage(sf.getMessage()); 
       if(sf.hasDetails()) { 
        logger.debug("sf has details");  
        Element eee = sf.getDetail(); 
        if(eee.hasAttributes()) { 
         NamedNodeMap nnm = eee.getAttributes(); 
         logger.debug("sf.details has " + nnm.getLength() + " attributes"); 
         for(int ii = 0 ; ii < nnm.getLength() ; ii++) { 
          Node nnode = nnm.item(ii); //WARNING Nodes are recursive structures 
          logger.debug(" attribute node value:" + nnode.getNodeValue()); 
         } 
        } 
        if(eee.hasChildNodes()) { 
         NodeList nl = eee.getChildNodes(); 
         logger.debug("sf.details has " + nl.getLength() + " child nodes"); 
         for(int ii = 0 ; ii < nl.getLength() ; ii++) { 
          Node nnode = nl.item(ii); 
          logger.debug(" child node value:" + nnode.getNodeValue()); 
         } 
        } 
       } else { 
        logger.debug("sf has no details");     
       } 
      } 
     } 
     logger.debug("exiting"); 
    } 

、ここではそれがログに記録するものです:

handleMessage] - entering 
handleMessage] - e is not null 
handleMessage] - e.getCause:org.springframework.orm.jpa.JpaSystemException: Could not open connection; nested exception is org.hibernate.exception.GenericJDBCException: Could not open connection 
handleMessage] - e.getMessage:Could not open connection; nested exception is org.hibernate.exception.GenericJDBCException: Could not open connection 
handleMessage] - e is instanceOf Fault 
handleMessage] - sf is not null 
handleMessage] - sf.getCause:org.springframework.orm.jpa.JpaSystemException: Could not open connection; nested exception is org.hibernate.exception.GenericJDBCException: Could not open connection 
handleMessage] - sf.getMessage:Could not open connection; nested exception is org.hibernate.exception.GenericJDBCException: Could not open connection 
handleMessage] - sf.getStatusCode:500 
handleMessage] - sf.getCode:Could not open connection; nested exception is org.hibernate.exception.GenericJDBCException: Could not open connection 
handleMessage] - sf has no details 
handleMessage] - exiting 

-/appended--

そこでここでは、故障コードに設定されていることを確認します500がサービスを終了する前にフォールトに表示されますが、ブラウザには表示されません。私は前に同様の問題を扱ってきた TIA、

まだ学習STEV

+0

ログ「FCを:」あなたのログファイル "om_fc:"が報告されます。 samは "frs:"と発音します。あなたは、このコードとこのログファイルが一緒に収まることを確認していますか? –

+0

はい。om_fcとom_frsとfcとfsrはすべて一意です。 sb.hasFault()は、ログファイルに見られるように、 "soap body does not fault"と証明されているので、fcとfsrはログに記録されません。 – user1201168

+0

あなたのコードをdebbugし、 "sb.hasFault()"が何をするかを確認することをお勧めします。少なくとも何をすべきかの兆候があるかもしれません。 –

答えて

3

。最後に問題はHTTPステータスコードでした。正しいHTTPステータスコードを持っていない

In case of a SOAP error while processing the request, the SOAP HTTP server MUST issue an HTTP 500 "Internal Server Error" response and include a SOAP message in the response containing a SOAP Fault element (see section 4.4) indicating the SOAP processing error.

http://www.w3.org/TR/2000/NOTE-SOAP-20000508/

は私のクライアントライブラリ(メトロ/ Glassfishのは)完全に障害区間を無視していました。これは、SOAP 1.1のためのものであることを

注意、しかし、私はこれがあなたに関連しているならば、あなたは仕様を読むことができる、SOAP 1.2のために、これはまた違っていると信じていますが、1.1を使用しているように見えます。あなたが戻ってきている

+0

興味深い。 Webサービスから返されたxmlにフォルトコードが表示されません。しかし、私はWebサービスを所有しており、私のアウトバウンドCXF FaultInterceptorのログを調べています.f.getStatusCodeが500を返す場所がわかります。私たちは正しい軌道に乗っていると思います - クライアントリゾルバではなく、サービス・インターセプタがシャットアウトしています。私は調査します。あなたの助けにThx。 11. – user1201168

+0

@ user1201168これで運がいい?私はこの事件が不思議です。 –

+0

は、私が発見したサービスでインターセプターを操作するには1)インターセプターをオフにすると、示されているようにソープフォールトが生成され、2)インターセプターをオンにして明示的に何かを投げないようにする。3)インターセプターをオンにして、新しいFault(new MyCustomException)を投げるようなものでは、まったくのsoapfaultではなく、むしろ不正確な200-Okの応答をもたらしました。 SoapUIを使用すると、サービスから戻ってくるもののテストが大幅に高速化されます。クライアントのインターセプタを起動させるまで、これをバックバーナーに入れようとしています。ご協力いただきありがとうございます。 – user1201168

3

石鹸の障害は、あなたのコードが障害を見つけるために失敗している理由かもしれない定義の名前空間が不足しています。

if(sb.hasFault()) { 
    logger.debug("soap body has fault"); 
    ... 

あなたは内部

<soap:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
0

FaultとURI http://schemas.xmlsoap.org/soap/envelope/で定義された名前の1を探してSoapBodyのすべての子要素を取得しますsb.hasFault()方法としてこれを含め試してみたいことがあります。何とかそれはそれを見つけることはありません。

しかし、あなたはこのようなものでSoapBodyオブジェクトから情報を抽出することができます

DOMSource source = (DOMSource)sb.getPayloadSource(); 
Node fault = source.getNode().getChildNodes().item(0); 

String faultcode = fault.getChildNodes().item(0) // "faultcode" 
         .getChildNodes().item(0) // text node inside "faultcode" 
          .getNodeValue(); 
String faultstring = fault.getChildNodes().item(1) // "faultstring" 
         .getChildNodes().item(0) // text node inside "faultstring" 
          .getNodeValue(); 

、または直接SoapBodyの子をキャストしようとすることによって:

SoapFault sff = null; 
DOMSource source = (DOMSource)sb.getPayloadSource(); 
Node fault = source.getNode().getChildNodes().item(0); 
if(fault instanceof SoapFault) { 
    sff = (SoapFault)fault; 
} 
関連する問題