關於JAX-RS

1. RESTful

關於什麼是RESTful網上已經有很多資料描述,比如這裏以及原文. 而這裏說到的JAXRS只是JAVA的一種實現

 

2. JAX-RS

目前有兩個版本的規範:JSR311和JSR339 .查看具體的規範文檔,發現提供了JSR339與JSR311相比提供了ClientAPI、Filter and Interceptor、Asynchronous Process等特性。下面簡單介紹下需要涉及的要點

 

resources及入參

在RESTful中將網絡中的任何資源描述爲Resources,而JAX-RS中則採用特定的annotation來標識該java類作爲一個網絡資源可供其他訪 問。同樣resource類也有生命週期和上下文環境的概念,一般來說當客戶端發起一個請求該resource類就實例化,當在正確的response後 就進入GC的環節。下面是一個POJO是如何成爲一個resource的,前面說了是依靠一系列的annotation

@Path標註javabean爲resource,一個resource至少需要一個@Path,可繼承

@Path("/rest")  
public class RESTPathService {  
  
    /** 
     *\\/rest/meth1 
     * @return 
     * @author Administrator 
     * @date 2013-3-9 
     */  
    @GET  
    @Path("/meth1")  
    public Response meth1() {  
        return Response.status(200).entity("/rest/meth1 is called").build();  
    }  
  
    /** 
     * \\/rest/meth2/2 OK 
     * \\/rest/meth2/a Error 
     * @return 
     * @author Administrator 
     * @date 2013-3-9 
     */  
    @GET  
    @Path("/meth2/{id : \\d+}")//id必須爲數字  
    public Response meth2() {  
        return Response.status(200).entity("/rest/meth2 is called").build();  
    }  

}  

@PathParam標註path template變量爲方法參數

@Path("/rest")  
public class RESTPathParamService {  
  
    @GET  
    @Path("/meth1/{name}")  
    public Response meth1(@PathParam("name") String name2) {  
        return Response.status(200).entity("/rest/meth1/" + name2 + " is called").build();  
    }  
  
    @GET  
    @Path("/meth2/{name}/{id : \\d+}")  
    public Response meth2(@PathParam("name") String name2, @PathParam("id") Integer id) {  
        return Response.status(200).entity("/rest/meth2/" + name2 + "/" + id + " is called").build();  
    }  
  
} 

@QueryParam標註查詢變量爲方法參數,如?name=robin&age=30將name、age作爲方法參數

@Path("/rest")  
public class RESTQueryParamService {  
  
    /** 
     * \\/rest/meth1?name=robin&age=30 
     *  
     * @param name 
     * @param age 
     * @return 
     * @author Administrator 
     * @date 2013-3-9 
     */  
    @GET  
    @Path("/meth1")  
    public Response meth1(@QueryParam("name") String name, @QueryParam("age") Integer age) {  
        return Response.status(200).entity("[name=" + name + ", age=" + age + "]").build();  
    }  
  
    /** 
     * \\/rest/meth2?name=robin&age=30 
     *  
     * @param info 
     * @return 
     * @author Administrator 
     * @date 2013-3-9 
     */  
    @GET  
    @Path("/meth2")  
    public Response meth2(@Context UriInfo info) {  
        return Response  
                .status(200)  
                .entity("[name=" + info.getQueryParameters().getFirst("name") + ", age="  
                        + info.getQueryParameters().getFirst("age") + "]").build();  
    }  
  
    /** 
     * \\/rest/meth3?username=robin&password=123123 
     *  
     * @param info 
     * @return 
     * @author Administrator 
     * @date 2013-3-9 
     */  
    @GET  
    @Path("/meth3")  
    public Response meth3(@QueryParam("") User user) {  
        return Response.status(200).entity("[name=" + user.getUsername() + ", password=" + user.getPassword() + "]")  
                .build();  
    }  
  
}  
@MatrixParam與QueryParam類似,還有FormParam,支持將參數封裝爲bean對象作爲方法參數傳入

@Path("/rest")  
public class RESTMatrixParamService {  
  
    /** 
     * \\/rest/meth1;name=robin;age=30; 
     *  
     * @param name 
     * @param age 
     * @return 
     * @author Administrator 
     * @date 2013-3-9 
     */  
    @GET  
    @Path("/meth1")  
    public Response meth1(@MatrixParam("name") String name, @MatrixParam("age") Integer age) {  
        return Response.status(200).entity("[name=" + name + ", age=" + age + "]").build();  
    }  
}

@CookieParam 獲取cookie作爲參數

@HeaderParam 獲取header作爲參數


@Path("/rest")  
public class RESTHeaderParamService {  
  
    @GET  
    @Path("/meth1")  
    public Response meth1(@HeaderParam("user-agent") String userAgent) {  
        return Response.status(200).entity("[user-agent=" + userAgent + "]").build();  
    }  
  
    @GET  
    @Path("/meth2")  
    public Response meth2(@Context HttpHeaders headers) {  
        return Response.status(200).entity("[user-agent=" + headers.getRequestHeader("user-agent").get(0) + "]")  
                .build();  
    }  
  
}

@Context注入資源的實例,如HttpHeader、UriInfo、Request等,見上面的例子

@DefaultValue標註一個參數的默認值

@Encoded參數編碼

methods

在resource類中用來標識該方法作爲一個request的HTTP請求方法,只有POJO中的public方法才能暴露爲一個resource方法。通常與@Path一起 使用。該類的annotation與HTTP方法一致:@GET,@POST,@PUT,DELETE,HEAD和OPTIONS.

 

返回類型

一個resource方法可以返回void,Response,GenericEntity以及其他任何的Java類型:

void 返回空的entry body和204的狀態碼

Response 可自行設定返回的狀態碼,如果未指定會根據response中的entry來判斷,如果entry爲null狀態碼爲204,否則爲200:

Response.status(200).entity(Object entry).build() 

GenericEntity 實際上是對返回對象的簡單包裝:public class GenericEntity<T>同樣對狀態碼和entry的關係遵循上面Response的原則

Other:一個實體對象即一個普通的POJO對象,爲空狀態碼204,不爲空狀態碼200

 

異常處理

簡單的說異常可以實現WebApplicationException或者採用Response返回特定的錯誤碼如500

 

uri模板

一個root resource類用@Path

我們常用@Path標註一個POJO類,來表示該類作爲一個root resource,而其他的相對路徑我們可以標註在方法或者子類的resource中。在annotation的值是自動編碼的,如

@Path("widget list/{id}")    
@Path("widget%20list/{id}")   

是等同的。同時也可以支持正則的請求路徑:

@Path("widgets/{path:.+}")   -->widgets/a/aa或widgets/a  
@Path("widgets/{id: \\d+}")   -->widgets/12  

MediaType

在JAX-RS中處理請求和相應的mediatype主要用@Consumes和@Produces可用在resource類或方法上

@Produces("text/html") 

如果任何類型都支持

@Produces("*/*") 

或者多個

@Produces("application/xml", "application/json") 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章