在CXF中默认的异常处理是无法满足开发需求,经常需要把异常信息转换为JSON或者XML格式,返回给客户的,这样就只能自定义异常处理了。
在对外提供接口的时候,如果出现异常,一般会通过JSON或XML将异常码及异常信息反回给客户,这在CXF中也很容易实现。
第一步:编写自己的异常处理类 InvokeFaultExceptionMapper
@Provider
public class InvokeFaultExceptionMapper implements ExceptionMapper {
public Response toResponse(Throwable ex) {
StackTraceElement[] trace = new StackTraceElement[1];
trace[0] = ex.getStackTrace()[0];
ex.setStackTrace(trace);
ResponseBuilder rb = Response.status(Response.Status.INTERNAL_SERVER_ERROR);
rb.type("application/json;charset=UTF-8");
rb.entity(ex);
rb.language(Locale.SIMPLIFIED_CHINESE);
Response r = rb.build();
return r;
}
}
第二部:加载InvokeFaultExceptionMapper
<jaxrs:server id="expGateway" address="/expGateway"> <jaxrs:inInterceptors> <ref bean="inMessageInterceptor"/> </jaxrs:inInterceptors> <jaxrs:outInterceptors> <ref bean="outMessageInterceptor"/> </jaxrs:outInterceptors> <jaxrs:serviceBeans> <ref bean="expGatewayImpl" /> </jaxrs:serviceBeans> <jaxrs:extensionMappings> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> </jaxrs:extensionMappings> <jaxrs:languageMappings> <entry key="en" value="en-gb" /> </jaxrs:languageMappings> <jaxrs:providers> <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/> <bean class="com.pml.service.outer.InvokeFaultExceptionMapper"/> </jaxrs:providers> </jaxrs:server>
第三步:测试
在你的接口中跑出异常试一试,结果如下
{"operate":null,"errCode":0,"errSubCode":"err.001","cause":null,"message":"ID值异常!","localizedMessage":"ID值异常!","stackTrace":[{"className":"com.pml.service.outer.ExpGatewayImpl","fileName":"ExpGatewayImpl.java","lineNumber":59,"methodName":"getUser","nativeMethod":false}]}
二、在深入些
看到上面异常返回的接口,发现很多一部分内容是无用,真正想给客户端只有 errCode":0,"errSubCode":"err.001“ ,"message":"ID值异常!"这部分内容。那我们对异常返回的内容进行过滤一下:
第一步:修改InvokeFaultExceptionMapper.java
@Provider
public class InvokeFaultExceptionMapper implements ExceptionMapper {
public Response toResponse(Throwable ex) {
StackTraceElement[] trace = new StackTraceElement[1];
trace[0] = ex.getStackTrace()[0];
ex.setStackTrace(trace);
ResponseBuilder rb = Response.status(Response.Status.INTERNAL_SERVER_ERROR);
rb.type("application/json;charset=UTF-8");
if (ex instanceof ServiceException) {//自定义的异常类
ServiceException e = (ServiceException) ex;
ServiceExceptionEntity entity=new ServiceExceptionEntity(e.getErrCode(),e.getErrSubCode(),e.getMessage());
rb.entity(entity);
}else{
rb.entity(ex);
}
rb.language(Locale.SIMPLIFIED_CHINESE);
Response r = rb.build();
return r;
}
}
其实增加了下面这部分代码
if (ex instanceof ServiceException) {//自定义的异常类
ServiceException e = (ServiceException) ex;
ServiceExceptionEntity entity=new ServiceExceptionEntity(e.getErrCode(),e.getErrSubCode(),e.getMessage());
rb.entity(entity);
}else{
rb.entity(ex);
}
多了对自定义异常的类型判断,如果是ServiceException异常,则进行处理,非ServiceException则进行走原路。(ServiceException是系统的自定义异常类,有三个属性(int errCode,String errSubCode,String message))
添加的代码中了ServiceExceptionEntity类,该类的代码如下
public class ServiceExceptionEntity implements Serializable {
/**
* 注释内容
*/
private static final long serialVersionUID = 1L;
public ServiceExceptionEntity(){}
public ServiceExceptionEntity(int errCode, String errSubCode, String message) {
super();
this.errCode = errCode;
this.errSubCode = errSubCode;
this.message = message;
}
/*错误码,默认为0*/
private int errCode;
/*错误子码,自定义该值*/
private String errSubCode;
private String message;
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public String getErrSubCode() {
return errSubCode;
}
public void setErrSubCode(String errSubCode) {
this.errSubCode = errSubCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
第二步:再在代码中抛出ServiceException异常,看下返回给客户端的代码是否为下面的几项
{"errCode":0,"errSubCode":"err.001","message":"ID值异常!","localizedMessage":"ID值异常!"}
添加的代码只对自定义的ServiceExceptino异常进行了处理,当然你还可以更多的异常处理。