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