一、服务器端配置
<bean id ="cxfServerExceptionMapper" class="com.iflashbuy.base.util.CxfServerExceptionMapper"/>
<jaxrs:server id="serviceContainer" address="/">
<jaxrs:features>
<cxf:logging />
</jaxrs:features>
<jaxrs:serviceBeans>
<!-- 商品接口 -->
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="feed" value="application/atom+xml" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="html" value="text/html" />
</jaxrs:extensionMappings>
<jaxrs:providers>
<ref bean="jacksonProvider" />
<ref bean="cxfServerExceptionMapper" />
</jaxrs:providers>
</jaxrs:server>
服务器端异常处理类
import java.util.Locale;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.ExceptionMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 服务器端异常处理
*
* @author limanman
* @date 2015年6月15日
*/
public class CxfServerExceptionMapper implements ExceptionMapper<Throwable> {
private Logger log = LoggerFactory.getLogger(CxfServerExceptionMapper.class);
@Override
public Response toResponse(Throwable e) {
ResponseBuilder rb = Response.status(Response.Status.INTERNAL_SERVER_ERROR);
log.error(e.getMessage(), e);
rb.entity(e.getMessage());
rb.type("text/x-json;charset=UTF-8");
rb.language(Locale.SIMPLIFIED_CHINESE);
Response r = rb.build();
return r;
}
}
二、客户端配置
<bean id="cxfClientExceptionMapper" class="com.iflashbuy.base.interceptor.CxfClientExceptionMapper" />
<!-- 商品模块 -->
<jaxrs:client id="productRestService"
serviceClass="com.fengshu.service.product.api.ProductService"
address="${service_api}">
<jaxrs:features>
<cxf:logging />
</jaxrs:features>
<jaxrs:providers>
<ref bean="jsonProvider" />
<ref bean="cxfClientExceptionMapper" />
</jaxrs:providers>
</jaxrs:client>
客户端异常处理类
/**
* cxf服务器端异常捕获
*
* @author limanman
* @date 2015年6月15日
*/
public class CxfClientExceptionMapper implements ResponseExceptionMapper<Throwable> {
@Override
public Throwable fromResponse(Response r) {
InputStream is = (InputStream) r.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder message = new StringBuilder();
String line = null;
try {
while ((line = br.readLine()) != null) {
message.append(line);
}
} catch (Exception e) {
// TODO: handle exception
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
}
return new ServiceException(message.toString());
}
}
假设是其它语言客户端去调用java webservice,如何去捕获呢,
方案:
cxf拦截器捕获到异常后将异常信息放到返回的头部信息里面,其它语音客户端当判断返回状态不是200后其它语音客户端通过头部信息获取异常原因
java端修改:
public class CxfServerExceptionMapper implements ExceptionMapper<Throwable> {
private Logger log = LoggerFactory.getLogger(CxfServerExceptionMapper.class);
@Override
public Response toResponse(Throwable e) {
ResponseBuilder rb = Response.status(Response.Status.INTERNAL_SERVER_ERROR);
if(StringUtil.isNotEmpty(e.getMessage())) {
rb.header("reason", e.getMessage());//如果希望client去捕获此异常最后用英文
}
log.error(e.getMessage(), e);
rb.entity(e.getMessage());
rb.type("text;charset=UTF-8");
rb.language(Locale.SIMPLIFIED_CHINESE);
Response r = rb.build();
return r;
}
}
ndoejs调用异常处理模仿
http.get(options, function (res) {
var result = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
result += chunk;
});
res.on('end', function () {
var statusCode = res.statusCode;
if (statusCode === 200) {
result = result ? JSON.parse(result) : false;
deferred.resolve(result);
} else if (statusCode === 204) { //针对操作成功,但没有内容返回
result = false;
deferred.resolve(result);
} else {
console.log(JSON.stringify(res.headers));
var errorReason = res.headers.reason;
console.error("get error statusCode: " + statusCode + " and request url is :" + JSON.stringify(url));
if (errorReason) {
console.error("error reason is " + errorReason);
}
deferred.reject("get error statusCode: " + statusCode + " and request url is :" + JSON.stringify(url));
}
});
}).on('error', function (e) {
console.error("invoke api failure:" + e);
deferred.reject('get Error:' + e.message, JSON.stringify(url));
});