我的CXF项目这两天要加入Exception,没想到这里CXF给我带来了很大麻烦,原来每个开源的东东都会有一点小瑕疵。
我定义了自已的Exception类,没想到的是throw了自定义的Exception的接口再用CXF自动生成wsdl时却有问题,我在服务端throw出来的自定义Exception在客户端接到却变成了SOAPFaultException。
经过了两天的仔细研究后,终于发现有几点是需要实现的:
一、自定义的Exception必需要实现getFaultInfo()方法,假设返回的类型是A,还必需要有以String和A对象为参数的构造方法。
二、必须给自定义的Exception加上WebFault的Annotation,注意FaultBean属性必须是A类型的全路径
三、必须给A类型加上XmlAccessorType和XmlType的Annotation。需要注意的两点是XmlType必须要有namespace属性,且必须是A类所属包的路径,另name属性也必须要和自定义的Exceptioni的FaultBean的属性值一致。如果不符合这两点,生成的wsdl文件会有错误。
四、自定义的Exception要覆盖Exception的getCause方法,而返回的要是一个SOAPFaultException,且返回值的faultCode和faultString属性会直接写在soap消息里,这点不做也可以,但是做了会增强soap消息的可读性。
这样以后,客户端终于可以catch到服务端throw的Exception了,下面将我的code贴出来:
WebOSException.java:
package org.nightstudio.proj.webos.error.management.bean.exception;
import java.util.ArrayList;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPFault;
import javax.xml.ws.soap.SOAPFaultException;
import javax.xml.ws.WebFault;
import org.nightstudio.proj.webos.error.management.bean.error.ErrorModule;
@WebFault(faultBean="org.nightstudio.proj.webos.error.management.bean.exception.WebOSFault", name="WebOSException", targetNamespace="
http://exception.bean.management.error.webos.proj.nightstudio.org/")
public class WebOSException extends Exception {
private static final long serialVersionUID = -3607154010022389749L;
private WebOSFault fault;
public WebOSException() {
super();
this.fault = new WebOSFault();
}
/*public WebOSException(String message) {
super(message);
this.fault = new WebOSFault();
}*/
/*public WebOSException(String message, Throwable cause) {
super(message, cause);
this.fault = new WebOSFault();
}*/
public WebOSException(String message, WebOSFault fault) {
super(message);
this.fault = fault;
}
/*public WebOSException(String message, Throwable cause, WebOSFault fault) {
super(message, cause);
this.fault = fault;
}*/
public WebOSException(WebOSFault fault) {
super();
this.fault = fault;
}
public WebOSException(ErrorModule module, String errorCode) {
super();
this.fault = new WebOSFault(module, errorCode);
}
public WebOSException(ErrorModule module, String errorCode, String arg) {
this(module, errorCode, new String[]{arg});
}
public WebOSException(ErrorModule module, String errorCode, String[] args) {
super();
this.fault = new WebOSFault(module, errorCode);
if (args != null) {
if (this.fault.getArgs() == null) {
this.fault.setArgs(new ArrayList<String>());
}
for (String arg : args) {
this.fault.getArgs().add(arg);
}
}
}
public WebOSFault getFaultInfo() {
return this.fault;
}
@Override
public Throwable getCause() {
SOAPFault fault;
try {
fault = SOAPFactory.newInstance().createFault();
fault.setFaultCode(new QName(String.valueOf(this.getFaultInfo().getModule()), this.getFaultInfo().getErrorCode()));
fault.setFaultString(this.getFaultInfo().toString());
SOAPFaultException ex = new SOAPFaultException(fault);
return ex;
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return super.getCause();
}
}
}
WebOSFault.java:
package org.nightstudio.proj.webos.error.management.bean.exception;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import org.nightstudio.proj.webos.error.management.bean.error.ErrorModule;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(namespace = "
http://exception.bean.management.error.webos.proj.nightstudio.org/", name = "org.nightstudio.proj.webos.error.management.bean.exception.WebOSFault", propOrder = {
"module",
"errorCode",
"args"
})
public class WebOSFault {
private ErrorModule module;
private String errorCode;
private List<String> args;
public WebOSFault() {
super();
this.module = ErrorModule.COMMON;
this.errorCode = "";
this.args = new ArrayList<String>();
}
public WebOSFault(ErrorModule module, String errorCode) {
super();
this.module = module;
this.errorCode = errorCode;
this.args = new ArrayList<String>();
}
public WebOSFault(ErrorModule module, String errorCode, List<String> args) {
super();
this.module = module;
this.errorCode = errorCode;
this.args = args;
}
public ErrorModule getModule() {
return module;
}
public void setModule(ErrorModule module) {
this.module = module;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public List<String> getArgs() {
return args;
}
public Object[] getArgArray() {
if (this.args == null) {
return null;
}
Object[] result = new Object[this.args.size()];
for (int i = 0; i < this.args.size(); i++) {
result[i] = this.args.get(i);
}
return result;
}
public void setArgs(List<String> args) {
this.args = args;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer(100);
buffer.append("ErrorModule: ").append(this.getModule()).append(", ");
buffer.append("ErrorCode: ").append(this.getErrorCode()).append(", ");
buffer.append("Arguments: [");
if (this.args != null) {
for (String arg : this.args) {
buffer.append(arg).append(", ");
}
} else {
buffer.append("null");
}
buffer.append("]");
return buffer.toString();
}
}