Jersey中的异常统一处理

Jersey中,对rest资源进行处理时,正常情况下会返回一个成功的Response,例如flag=1或者一个json。

public Response get(@PathParam("p") String p) throws MyException {
        logger.info("rest/test ...");
        if ("1".equals(p)) {
            throw new MyException("test myException..");
        }
        return Response.status(Response.Status.OK).type(MediaType.APPLICATION_JSON).build();
    }

但有时候因为各种原因:例如参数错误或者业务要求,需要抛出runtimeException或者自定义异常(权限不够等),我们的代码如果对每个异常都进行处理并返回的话,程序就会显得很拖沓。

如果不处理异常,任由系统抛出的话,前端就会得到http status 404之类的返回,而前端的兄弟是希望任何时间都应该得到一个code,而不是http 404之类的返回。

这个时候,我们就需要对异常进行统一处理,避免到处都是处理异常的代码。

 

首先是Jersey的配置

maven

<!--jersey-->
<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
    <version>2.0</version>
</dependency>

<!--JAXB API-->
<dependency>
    <groupId>javax.xml.ws</groupId>
    <artifactId>jaxws-api</artifactId>
    <version>2.1</version>
</dependency>

<!-- Json支持 -->
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.12</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.12</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-jaxrs</artifactId>
    <version>1.9.12</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.4.1</version>
</dependency>

web.xml

    <!-- RestServiceServlet -->
    <servlet>
        <servlet-name>RestfulContainer</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.sharp.controller.rest.MyApplication</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>RestfulContainer</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

注意其中的MyApplication...

 自定义异常

public class MyException extends RuntimeException {

    /**  */
    private static final long serialVersionUID = -9095798995958029993L;

    private String            msg;

    /**
     * Getter method for property <tt>msg</tt>.
     * 
     * @return property value of msg
     */
    public String getMsg() {
        return msg;
    }

    /**
     * Setter method for property <tt>msg</tt>.
     * 
     * @param msg value to be assigned to property msg
     */
    public void setMsg(String msg) {
        this.msg = msg;
    }

    public MyException(String msg) {
        this.msg = msg;
    }
}

异常mapper

@Provider
public class MyExceptionMapper implements ExceptionMapper<MyException> {

    /** 
     * @see javax.ws.rs.ext.ExceptionMapper#toResponse(java.lang.Throwable)
     */
    public Response toResponse(MyException ex) {
        return Response.status(Response.Status.OK).entity(ex.getMsg())
            .type(MediaType.APPLICATION_JSON).build();
    }

}

注册初始化,这个文件要与web.xml中相对应。

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        // register(HelloResource.class);
        packages("com.sharp.controller.rest");
        // register(RestTestController.class);
    }
}

最后就是rest的入口

@Path("/test")
public class RestTestController {
    private final Log logger = LogFactory.getLog(getClass());

    @GET
    @Path("/get/{p}")
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response get(@PathParam("p") String p) throws MyException {
        logger.info("rest/test ...");
        if ("1".equals(p)) {
            throw new MyException("test myException..");
        }
        return Response.status(Response.Status.OK).type(MediaType.APPLICATION_JSON).build();
    }

}

这里我们的业务就是如果传入的参数是1的话,就抛出异常,否则就是一个正常的结果。

 

最后访问http://127.0.0.1:8080/batis/rest/test/get/1 ,就可以看到虽然抛出了一个异常,但前端还是得到了一个http status 200的正确返回,只不过返回数据显示有个异常。

 

这样的话,我们在rest的service中就可以只考虑业务流程,而不需要使用try catch 对业务进行包围处理了。

 

posted on 2017-02-04 15:30  马来亚  阅读(2942)  评论(0编辑  收藏  举报

导航