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 對業務進行包圍處理了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM