Announcement Announcement Module
Collapse
No announcement yet.
ws:outbound-gateway SoapFault handlign detail part Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ws:outbound-gateway SoapFault handlign detail part

    I have ws:inbound-gateway with ws:outbound-gateway inside.

    ws:outbound-gateway invokes service and got soapFault.


    Code:
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
       <soap:Body>
          <soap:Fault>
             <faultcode>soap:Server</faultcode>
             <faultstring>My Error text</faultstring>
             <detail>
                <ns1:MyCustomException xmlns:ns1="http://mkpackage/">
                   <category xmlns:ns2="http://mkpackage/">category X</category>
                   <details xmlns:ns2="http://mkpackage/">My Error text</details>
                </ns1:MyCustomException>
             </detail>
          </soap:Fault>
       </soap:Body>
    </soap:Envelope>
    In my ErrorUnwrapper I can read <faultstring>

    Code:
    @MessageEndpoint
    public class ErrorUnwrapper {
    
    	@Transformer
    	public Message<?> transform(ErrorMessage errorMessage) {
    ..		
    	
    		String exceptionMessage = ((MessagingException) errorMessage.getPayload()).getCause().getMessage();
    ...
    }
    My question is:

    How can I read detail in my flow inside fault-message-resolver or ErrorUnwrapper from error-channel chain ?

    regards Marcin
    Last edited by marcin.kasinski; Sep 13th, 2012, 02:19 AM.

  • #2
    The default fault-message-resolver is a SoapFaultMessageResolver; this means the cause should be a SoapFaultClientException, which has the fault string as its message.

    The entire SoapFault object is available using the
    Code:
    getSoapFault();
    method on the SoapFaultClientException.

    Comment


    • #3
      Thanks for reply.

      Now I can read soap as string from my fault message resolver

      public class SimpleFaultMessageResolver implements FaultMessageResolver {

      public void resolveFault(WebServiceMessage message) {

      SoapMessage soapMessage = (SoapMessage) message;


      ...
      Now I know that service invoked by my ws:outbound-gateway throws custom SoapFault with detail part:

      <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
      <soap:Fault>
      <faultcode>soap:Server</faultcode>
      <faultstring>My Error text</faultstring>
      <detail>
      <ns1:MyCustomException xmlns:ns1="http://mkpackage/">
      <category xmlns:ns2="http://mkpackage/">category X</category>
      <details xmlns:ns2="http://mkpackage/">My Error text</details>
      </ns1:MyCustomException>
      </detail>
      </soap:Fault>
      </soap:Body>
      </soap:Envelope>
      I know I can read String with entire Envelope.

      Is there simpler way to read this detail part ?

      I have correct MyCustomExceptionBean based on soap:Fault above.

      Can I check (in resolver or other place) is it standard MyCustomExceptionBean throws by service ?

      How can I generate MyCustomExceptionBean from WebServiceMessage to make it easier ?

      Comment


      • #4
        I thought I already explained that. The default SoapFaultMessageResolver throws a SoapFaultClientException.

        You can call getSoapFault() on that, and then explore the SoapFault at will - such as

        Code:
        for (SoapFaultDetailElement element : fault.getFaultDetails()) {
            QName qname = element.getName();
        ...
        
        }
        If you want to do it in a custom resolver instead, just extract the fault from the message first - see how the SoapFaultClientException does it...

        Code:
                SoapBody body = faultMessage.getSoapBody();
                soapFault = body != null ? body.getFault() : null;

        Comment


        • #5
          Thanks for reply.

          I put it this way:

          I know I can do it as you explained.

          SoapMessage soapMessage = (SoapMessage) message;
          SoapBody soapBody = soapMessage.getSoapBody();

          SoapFault soapFault = soapBody.getFault();
          SoapFaultDetail soapFaultDetail=soapFault.getFaultDetail();




          for(Iterator it = soapFaultDetail.getDetailEntries(); it.hasNext() {

          SoapFaultDetailElement soapFaultDetailElement=(SoapFaultDetailElement) it.next();

          // System.out.println(soapFaultDetailElement.getSourc e());
          System.out.println("soapFaultDetailElement " + soapFaultDetailElement.getName());
          ...

          My problem is:


          Can I convert SoapFault into my custom JAVAException class ?


          I dont want to iterate SoapFaultDetailElement manually.

          I want to convert SoapFault into my CustomException class.
          This class was generated by wsdltoJava and I know it is based on custom soapFault generated by invoked service.

          MyCustomExceptionBean customexception=getCustomExceptionFrom(soapMessage );

          x=customexception.getCategory();
          y=customexception.getDeatils();
          Do you understand my problem ?

          Comment


          • #6
            I don't understand your problem.

            You have to do the details extraction from the SoapFault someplace.

            You can either do it in a custom FaultMessageResolver and throw your custom exception, or do it in a utility method, to convert a SoapFaultClientException to your custom exception.

            Comment


            • #7
              Yes . I have to do the details extraction from the SoapFault generated by service.

              To resolver fault from this remote service I use custom FaultMessageResolver in my out gateway.

              Service generates SoapFault.

              <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
              <soap:Body>
              <soap:Fault>
              <faultcode>soap:Server</faultcode>
              <faultstring>My Error text</faultstring>
              <detail>
              <ns1:MyCustomException xmlns:ns1="http://mkpackage/">
              <category xmlns:ns2="http://mkpackage/">category X</category>
              <details xmlns:ns2="http://mkpackage/">My Error text</details>
              </ns1:MyCustomException>
              </detail>
              </soap:Fault>
              </soap:Body>
              </soap:Envelope>

              As you can see this is custom SoapFault. Inside detail part there is custom Exception object.
              Here this object is quite simple because it is just example. It could be very complicated.

              using wsdl2java (Apache CXF 2.6.1) I generated MyCustomExceptionBean java bean class from service wsdl.


              package mkpackage.jaxws;

              import javax.xml.bind.annotation.XmlAccessType;
              import javax.xml.bind.annotation.XmlAccessorType;
              import javax.xml.bind.annotation.XmlRootElement;
              import javax.xml.bind.annotation.XmlType;

              /**
              * This class was generated by Apache CXF 2.6.1
              * Thu Sep 13 10:17:33 CEST 2012
              * Generated source version: 2.6.1
              */

              @XmlRootElement(name = "MyCustomException", namespace = "http://mkpackage/")
              @XmlAccessorType(XmlAccessType.FIELD)
              @XmlType(name = "MyCustomException", namespace = "http://mkpackage/", propOrder = {"category", "details", "message"})

              public class MyCustomExceptionBean {

              private java.lang.String category;
              private java.lang.String details;
              private java.lang.String message;

              public java.lang.String getCategory() {
              return this.category;
              }

              public void setCategory(java.lang.String newCategory) {
              this.category = newCategory;
              }

              public java.lang.String getDetails() {
              return this.details;
              }

              public void setDetails(java.lang.String newDetails) {
              this.details = newDetails;
              }

              public java.lang.String getMessage() {
              return this.message;
              }

              public void setMessage(java.lang.String newMessage) {
              this.message = newMessage;
              }

              }

              Now I have 2 options to read fault info inside my resolver:

              -use SoapFaultDetail and read in loop tags inside. (I can do it)

              -automatically create MyCustomExceptionBean from WebServiceMessage, SoapMessage or SoapFault inside my resolver. For me it is easier to read custom detail from Fault object using my own MyCustomExceptionBean rather than SoapFaultDetail .


              Is it clear now ?
              Last edited by marcin.kasinski; Sep 13th, 2012, 08:56 AM.

              Comment


              • #8
                Is it clear now ?
                Not really.

                If you are simply saying you want to use JAXB to convert the fault string to a MyCustomExceptionBean object then, er... use JAXB to convert the fault string to a MyCustomExceptionBean.

                spring-oxm provides a convenient unmarshaller for JAXB... http://static.springsource.org/sprin....html#oxm-jaxb

                Comment

                Working...
                X