RESTEasy中的通用异常处理ExceptionMapper
Posted Heaven-Wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RESTEasy中的通用异常处理ExceptionMapper相关的知识,希望对你有一定的参考价值。
RESTEasy是JBoss提供的一个Restful基础框架,使用它我们可以很方便的构建我们的Restful服务,而且它也完全符合Java的JAX-RS2.0标准,很多第三方Restful框架也都是基于RESTEasy开发的。
在任何框架中都不可避免的涉及到异常处理,Restful框架也是如此。按照我们一般传统异常处理方式,在Restful的最外层,我们一般会对所有的业务调用都加上try catch,以免异常被用户接收到,比如我们有这么一个Restful服务:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.spi.validation.ValidateRequest;
@Path("/rest")
public class UserApi
@Autowire
UserService userService;
@Path("/users/id")
@GET
@ValidateRequest
public Response getUserBId ( @PathParam("id") String id ) throws RuntimeException
try
User user=userService.getUser(id);
catch(IllegalArgumentException e)
//if exception occured
return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
catch(Exception e)
//if exception occured
return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
//if success
return Response.ok().entity("User with ID " + id + " found !!").build();
上面UserApi接口中的getUserBId()方法调用了userService.getUser()服务,这个服务会抛出一些异常,UserApi需要捕获异常并返回客户的一个错误的响应。还有一点我们一般会在API层catch一个Exception异常,也就是捕获所有可能发生的异常情况,以免前端出现不友好的错误提示。
这么做也没什么问题,但是我们的接口不只是一个,每个接口需要进行try catch来处理异常,这么做显然不符合我们的编程思想,我们希望把所有异常集中到一个地方处理。
如果我们的Restful框架是基于RESTEasy的,那么我们就可以使用ExceptionMapper来实现一个通用异常处理类。
使用ExceptionMapper进行通用异常处理
ExceptionMapper是provider的一个协议,它会将Java的异常映射到Response对象。所以要进行通用异常处理,我们只需要写一个类来实现ExceptionMapper接口,并把它声明为一个provider即可:
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class MyApplicationExceptionHandler implements ExceptionMapper<MyApplicationException>
@Override
public Response toResponse(Exception exception)
return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
上面的ExceptionMapper的实现已经写好了,下面我们写个Restful API来测试下:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.spi.validation.ValidateRequest;
@Path("/rest")
public class UserApi
@Autowire
UserService userService;
@Path("/users/id")
@GET
@ValidateRequest
public Response getUserBId ( @PathParam("id") String id ) throws RuntimeException
try
User user=userService.getUser(id);
catch(IllegalArgumentException e)
throw new RuntimeException("id is not a number !!");
return Response.ok().entity("User with ID " + id + " found !!").build();
在这个接口中,我们并没有对异常做特殊处理,也没有catch一个Exception异常,仅仅是把异常抛出,而所有的异常处理都集中在了MyApplicationExceptionHandler中。
我们测一下这个接口,首先我们写一个合法的请求:
http://localhost:8080/RESTEasyExceptionMapperDemo/rest/users/1
我们再写一个不合法的请求,请求的参数是个字符串而不是数值:
http://localhost:8080/RESTEasyExceptionMapperDemo/rest/users/abc
以上是关于RESTEasy中的通用异常处理ExceptionMapper的主要内容,如果未能解决你的问题,请参考以下文章