Jersey框架http code自定义以及异常处理
背景:使用jersey框架,原CloudSOP使用的ServiceException定义异常带有http code,统一被转为500。比如,403码变成500,对原有界面提示产生影响。
分析:原CloudSOP使用DispatcherServlet处理http code和异常消息。Jersey有自己的异常处理机制,ServletContainer是所有servlet入口,也就是说rest服务总的接口人。由于Jersey不识别ServiceException,所以把它当成普通异常,抛出500。所以,必须使用Jersey提供的异常机制解决。
实现ExceptionMapper接口,参考代码如下:
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import com.huawei.bsp.log.OssLog;
import com.huawei.bsp.log.OssLogFactory;
import com.huawei.bsp.remoteservice.exception.ServiceException;
/**
* 必须添加该注解使得在程序的任何地方发生运行时异常时,自动的进行异常统一处理
* 同时该类要能够被Jersey扫描到
*/
@Provider
public class ExceptionMappingResource implements ExceptionMapper<Exception>
{
private static final OssLog LOG = OssLogFactory.getLog(ExceptionMappingResource.class);
@Override
public Response toResponse(Exception exception)
{
ResponseBuilder responseBuilder = null;
if (exception instanceof ServiceException
&& ((ServiceException)exception).getHttpCode() == HttpServletResponse.SC_FORBIDDEN)
{
responseBuilder = Response.status(Response.Status.FORBIDDEN);
}
else
{
// 没catch住的异常打印日志,方便快速定位问题
LOG.error("find uncatch exception", exception);
responseBuilder = Response.status(Response.Status.INTERNAL_SERVER_ERROR);
}
return responseBuilder.build();
}
}
然后,要让Jersey能识别,要在ResourceConfig实现里,加上:
register(ExceptionMappingResource.
class
);
Jersey使用javax.ws.rs.core.Response响应请求,支持各种http code异常转型,也可以加返回消息:
Response.ok(object).status(Response.Status.FORBIDDEN);
这样,原有异常提示功能就能支持了。