Nav
You are viewing an older version of this topic. To go to a different version, use the version menu at the upper-right. +

Customize a Message Thrown by a SoapFault

APIkit for SOAP uses the Apache CXF Framework to manage items related to SOAP messages. There is no connection between the exceptions handled internally and Mule exception strategies. If you want to customize the message thrown by a SoapFault, you can use the CXF interceptor.

This document uses the following product versions:

  • Anypoint Studio 6.4.4

  • Mule EE 3.9.0

  • SoapKit 1.0.3

  • SoapUI 5.4.0

Locate the Interceptor Components

  1. Open Studio 6 and import the attached project custom-soap-fault.zip file.

  2. In the unzipped file, locate the interceptor SoapFaultOutInterceptor.java in the src/main/java/org/example folder.

    Customizing the message from a SoapFault consists of editing the SoapFaultOutInterceptor.java and changing this statement as shown below:

    final Throwable myCustomError = new Throwable("This is a custom error message !!!");
    
                
             
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    
    package org.example;
    
    import javax.xml.stream.XMLStreamException;
    
    import org.apache.cxf.binding.soap.SoapFault;
    import org.apache.cxf.binding.soap.interceptor.Soap11FaultOutInterceptor;
    import org.apache.cxf.interceptor.Fault;
    import org.apache.cxf.message.Message;
    import org.apache.cxf.phase.AbstractPhaseInterceptor;
    import org.apache.cxf.phase.Phase;
    
    /**
     * This interceptor runs just before create the SoapFault.
     * At this point you can change the exception used to create the SoapFault message
     * In this interceptor we are only change the exception when it is an instance
     * of XMLStreamException but you can adapt this behavior.
     */
    
    public class SoapFaultOutInterceptor extends AbstractPhaseInterceptor<Message> {
    
            public SoapFaultOutInterceptor() {
                    super(Phase.PREPARE_SEND);
                    this.getBefore().add(Soap11FaultOutInterceptor.class.getName());
                    // If you are using SOAP version 1.2
                    //this.getBefore().add(Soap12FaultOutInterceptor.class.getName());
            }
    
            @Override
            public void handleMessage(final Message message) {
                       System.out.println("********** Start Custom SoapFault Interceptor ***********");
    
                       // Original SoapFault
                 final Fault f = (Fault) message.getContent(Exception.class);
    
                 // Only Customize XMLStreamException
                 if (f.getCause() instanceof XMLStreamException) {
    
                         System.out.println("Original SoapFault:");
                         System.out.println("\tClass: " + f.getCause().getClass());
                         System.out.println("\tFaultCode :" + f.getFaultCode());
                          System.out.println("\tCause :" + f.getCause().getMessage());
    
                         final Throwable myCustomError = new Throwable("This is a custom error message !!!");
                         final SoapFault myCustomFault = new SoapFault("Custom Error", myCustomError, f.getFaultCode());
    
                         message.setContent(Exception.class, myCustomFault);
                 }
                 System.out.println("********** End Custom SoapFault Interceptor ***********");
            }
    }

    In Studio, in the config file src/main/resource/cxf.xml are references to the interceptor:

    
                
             
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:cxf="http://cxf.apache.org/core"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://cxf.apache.org/core
            http://cxf.apache.org/schemas/core.xsd
                    http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
    <!--         <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" id="logInbound"/> -->
    <!--         <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" id="logOutbound"/> -->
            <bean class="org.example.SoapFaultOutInterceptor" id="soapfaultOutInterceptor"/>
    
            <cxf:bus>
                    <cxf:features>
                            <cxf:logging/>
                    </cxf:features>
    
    <!--                 <cxf:inInterceptors> -->
    <!--                         <ref bean="logInbound"/> -->
    <!--                 </cxf:inInterceptors> -->
    
    <!--                 <cxf:outInterceptors> -->
    <!--                         <ref bean="logOutbound"/> -->
    <!--                 </cxf:outInterceptors> -->
    
                    <cxf:outFaultInterceptors>
                            <ref bean="soapfaultOutInterceptor"/>
                    </cxf:outFaultInterceptors>
    
    <!--                 <cxf:inFaultInterceptors> -->
    <!--                         <ref bean="logInbound"/> -->
    <!--                 </cxf:inFaultInterceptors> -->
            </cxf:bus>
    </beans>

Run the Application

Run the application from Studio.

Run the application from Studio

The application should deploy, and the following messages should appear in the Console:


         
      
1
2
3
4
**********************************************************************
* - - + APPLICATION + - - * - - + DOMAIN + - -  * - - + STATUS + - - *
**********************************************************************
* soap-SE-7813    * default                        * DEPLOYED        *

Send a SoapUI Request

  1. Using SoapUI, send a request to the deployed Mule app on port 8087.

    If you send an invalid XML, you see the SoapFault with the message customized in the SoapFaultOutInterceptor:

    SoapFault message in Studio

    The console log should look like:

    
                
             
    1
    2
    3
    4
    5
    6
    7
    
    ********** Start Custom SoapFault Interceptor ***********
    Original SoapFault:
            Class: class com.ctc.wstx.exc.WstxParsingException
            FaultCode :{http://schemas.xmlsoap.org/soap/envelope/}Client
            Cause :Unexpected close tag </soapenv:Body>; expected </soapenv:Envelope>.
     at [row,col {unknown-source}]: [9,17]
    ********** End Custom SoapFault Interceptor ***********

    Studio project structure

  2. To get rid of the console exception, you can change the log severity.

  3. Include this line (already included but commented out) in the src/main/resources/log4j2.xml file:

    
                
             
    1
    2
    
    <!-- CXF, avoid log for invalid XML messages, SE-7813 changing the severity to ERROR -->
     <AsyncLogger name="org.apache.cxf.phase.PhaseInterceptorChain" level="ERROR"/>

We use cookies to make interactions with our websites and services easy and meaningful, to better understand how they are used and to tailor advertising. You can read more and make your cookie choices here. By continuing to use this site you are giving us your consent to do this.

+