How to map the SOAP fault message with a custom exception?

I was working on some customer issues about throwing a SOAP fault back to the client in CXF recently. It made me think it's a common issue that I should blog about it.
First, what does the SOAP Fault message look like ?

 

Just like the SOAP message, the SOAP fault has a generic message structure,  it consists of faultcode, faultstring and detail elements. 

How can SOAP fault message turn into a custom Exception that you can you can use in the Java world? The key is the child element of the detail element.
From the upper example, you can see there an UnknownPersonFault element in the detail element, and this Fault message will be mapped to the UnknownPersonFault exception as we want when  the CXF client receives this message.

Let's take a look at the UnknowPersonFault Java code to see how this part works.

package org.apache.camel.wsdl_first;

import javax.xml.ws.WebFault;
@WebFault(name = "UnknownPersonFault", targetNamespace = "http://camel.apache.org/wsdl-first/types")
public class UnknownPersonFault extends Exception {
    public static final long serialVersionUID = 20110126200613L;
    
    private org.apache.camel.wsdl_first.types.UnknownPersonFault unknownPersonFault;

    public UnknownPersonFault() {
        super();
    }
    
    public UnknownPersonFault(String message) {
        super(message);
    }
    
    public UnknownPersonFault(String message, Throwable cause) {
        super(message, cause);
    }

    public UnknownPersonFault(String message, org.apache.camel.wsdl_first.types.UnknownPersonFault unknownPersonFault) {
        super(message);
        this.unknownPersonFault = unknownPersonFault;
    }

    public UnknownPersonFault(String message, org.apache.camel.wsdl_first.types.UnknownPersonFault unknownPersonFault, Throwable cause) {
        super(message, cause);
        this.unknownPersonFault = unknownPersonFault;
    }

    public org.apache.camel.wsdl_first.types.UnknownPersonFault getFaultInfo() {
        return this.unknownPersonFault;
    }
}

 

Wait a minute, why there is another UnknownPersonFault? Let's dig into the new found one.

 

 

package org.apache.camel.wsdl_first.types;

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


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="personId" type="{http://www.w3.org/2001/XMLSchema}string"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "personId"
})
@XmlRootElement(name = "UnknownPersonFault")
public class UnknownPersonFault {

    @XmlElement(required = true)
    protected String personId;

    /**
     * Gets the value of the personId property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getPersonId() {
        return personId;
    }

    /**
     * Sets the value of the personId property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setPersonId(String value) {
        this.personId = value;
    }

}

 

Oh, this one is the real UnknownPersonFault which can be used by JAXB to marshal and unmarshal the message. And it is wrapped by an exception which is annotated with @WebFault. This @WebFault will be helpful when CXF wants to create a custom exception from a SOAP fault message. Because CXF can look up the detail child element QName for it.

And when CXF tries to marshal this custom exception, it can easily write the detail child element by marshaling the exception.getFaultInfo().So when we throw the exception from the SEI , we should use the wrapped exception instead of the JAXB annotated class which is not a real exception, and you also need to pass the JAXB fault class instance into the exception to fill the detail element like this.

 

org.apache.camel.wsdl_first.types.UnknownPersonFault faultDetail = new org.apache.camel.wsdl_first.types.UnknownPersonFault();
                        faultDetail.setPersonId("");
                        UnknownPersonFault fault = new UnknownPersonFault("Get the null value of person name", faultDetail);
                        throw fault;

 

If the detail element has no child element, the CXF client will just create a common  SOAPFaultExceptionbecause it will have no information about how to map the SOAP Fault message into a custom exception.

 

http://willemjiang.blogspot.com/2011/01/how-to-map-soap-fault-message-with.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值