在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>
第三步:测试
扫描二维码关注公众号,回复:
792988 查看本文章
在你的接口中跑出异常试一试,结果如下
{"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异常进行了处理,当然你还可以更多的异常处理。