guice resteasy
http://www.cnblogs.com/ydxblog/p/7891224.html
http://blog.csdn.net/withiter/article/details/7349795
本章介紹REST架構、RESTful web service和JAX-RS(Java API for RESTful Web Service,JSR 311)。
JAX-RS的參考實現Jersey實現了對JSR 311中定義的注解的支持,使得使用Java編程語言開發RESTful web service變得簡單。
如果是使用GalssFish服務器,可以使用Update Tool安裝Jersey例子和文檔。使用Update Tool的教程見第62頁的“Java EE 6教程組件”。Jersey例子和文檔位於Update Tool的Available Add-ons中。
什么是RESTful Web Services
RESTful web service是創建來能在web更好的運行的web service。REST是一種架構類型,指定了如統一的接口等應用於web service的約束。REST提供了如性能、可擴展性和可變性等特性,使得service能夠更好的在web上工作。在REST框架中,數據和功能被認為是資源,是通過URI來訪問的,通常是web鏈接。資源是通過使用一組簡單的、定義良好的操作來生效。REST的架構方式限定了客戶/服務器架構,是設計來使用無狀態的通信協議的,通常是HTTP。在REST框架類型中,客戶端和服務器使用標准的接口和協議交換資源的representation。
下面的原則使得RESTful的應用程序簡單、輕量並快捷:
通過URI確定資源:一個RESTful的web service會公開一組資源,這組資源確定了和客戶端互動的目標。資源是通過URI來確定的,URI為service和資源提供了全球的地址空間。更多的信息見第239頁的“@Path注解和URI路徑模版”。
統一的接口:資源是通過固定的操作PUT,GET,POST和DELETE來創建、讀取、修改和刪除的。PUT會創建一個新的資源,DELETE會刪除一個資源。GET會獲取資源的當前狀態。POST將資源的狀態轉變成新的值。更多信息見底241頁的“對HTTP資源的響應”。
自描述的消息:資源和它們的表現是解耦的,因此可以以不同的格式來訪問,如HTML,XML,純文本,PDF,JPEG,JSON等。關於資源的元數據是有效的並且用來完成控制緩存、檢測傳輸錯誤、商討合適的表現格式、執行身份驗證和訪問控制等。更多信息見第241頁的“對HTTP資源的響應”和第243頁的“使用實體提供者來映射HTTP response和request的實體段”。
使用超鏈接的無狀態的互動:和資源的互動都是無狀態的,也就是說,request消息是自包含的。無狀態的互動是基於顯示狀態轉換的概念的。如URI重寫、cookies和隱藏的表單字段等技術是為了交換狀態而存在的。狀態可以被嵌套在response消息中來指向互動的將來有效的狀態。更多信息見“使用實體提供者來映射HTTP response和request的實體段”和JAX-RS Overview文檔中的“Building URIs”。
創建RESTful的Web根資源類
根資源類(Root resource classes)是由@Path注解標記的POJO或者至少有一個方法有@Path注解或請求方法指示符注解(@GET,@PUT,@POST或@DELETE)的POJO。
資源方法(resource method)是資源類中含有請求方法指示符注解的方法。
本節中將會解釋怎樣使用JAX-RS來注解Java類來創建RESTful的web service。
使用JAX-RS來開發RESTful web service
JAX-RS是一個Java編程語言接口,被設計用來簡化使用REST架構的應用程序的開發。
JAX-RS API使用Java編程語言的注解來簡化RESTful web service的開發。開發人員使用JAX-RS的注解修飾Java編程語言的類文件來定義資源和能夠應用在資源上的行為。JAX-RS的注解是運行時的注解,因此運行時的映射會為資源生成輔助類和其他的輔助文件。包含JAX-RS資源類的Java EE應用程序中資源是被配置好的,輔助類和輔助文件是生成的,資源通過被發布到Java EE服務器上來公開給客戶端。
下表列出了JAX-RS定義的一些Java注解以及怎樣使用它們的簡要的描述。更進一步的JAX-RS的API見http://download.oracle.com/javaee/6/api。
注解 |
描述 |
@Path |
@Path注解的值是一個相對的URI路徑,這個路徑指定了該Java類的位置,例如/helloworld。在這個URI中可以包含變量,例如可以獲取用戶的姓名然后作為參數傳入URI中:/helloworld/{username}。 |
@GET |
@GET注解是請求方法指示符,這個指示符注解的Java方法會處理HTTPGET請求。資源的行為由資源回應的HTTP方法決定。 |
@POST |
@POST注解是請求方法指示符,這個指示符注解的Java方法會處理HTTPPOST請求。資源的行為由資源回應的HTTP方法決定。 |
@PUT |
@PUT注解是請求方法指示符,這個指示符注解的Java方法會處理HTTPPUT請求。資源的行為由資源回應的HTTP方法決定。 |
@DELETE |
@DELETE注解是請求方法指示符,這個指示符注解的Java方法會處理HTTPDELETE請求。資源的行為由資源回應的HTTP方法決定。 |
@HEAD |
@HEAD注解是請求方法指示符,這個指示符注解的Java方法會處理HTTPHEAD請求。資源的行為由資源回應的HTTP方法決定。 |
@PathParam |
@PathParam注解是可以抽取並用在資源類中的一類參數。URIpath參數是從請求的URI中抽取的,而且參數的名稱和@Path注解中定義的變量名對應。 |
@QueryParam |
@QueryParam注解是可以抽取並在資源類中使用的一類參數。Query參數是從請求URI的查詢參數中抽取的。 |
@Consumes |
@Consumes注解是用來指定資源能夠接受的客戶發送的MIME媒體類型。 |
@Produces |
@Produces注解用來指定資源能夠生成並發送給客戶端的MIME媒體類型,例如“text/plain”. |
@Provider |
@Provider注解用在任何對JAX-RS運行時(如MessageBodyReader和MessageBodyWriter)有意義的事物上。對HTTP請求,MessageBodyReader用來將HTTP請求實體段映射為方法參數。在響應的時候,返回的值使用MessageBodyWriter來映射成HTTP響應實體段。如果應用程序需要提供其他的元數據,如HTTP頭或不同的狀態代碼,方法可以返回一個打包了實體的Response,該Response可以使用Response.ResponseBuilder創建。 |
JAX-RS應用程序概況
下面的代碼例子是一個非常簡單的根資源類,使用了JAX-RS注解:
- package com.sun.jersey.samples.helloworld.resources;
- import javax.ws.rs.GET;
- import javax.ws.rs.Produces;
- import javax.ws.rs.Path;
- // The Java class will be hosted at the URI path "/helloworld"
- @Path("/helloworld")
- public class HelloWorldResource {
- // The Java method will process HTTP GET requests
- @GET
- // The Java method will produce content identified by the MIME Media
- // type "text/plain"
- @Produces("text/plain")
- public String getClichedMessage() {
- // Return some cliched textual content
- return "Hello World";
- }
- }
隨后的幾節中我們會詳細描述這個例子中使用的注解。
@Path注解的值是一個相對的URI路徑。在上面的例子中,這個Java類會放在/helloworld這個路徑下。上面的例子中使用的是靜態的URI路徑,是最簡單的例子。在URI中,我們可以包含變量,對於這樣的包含變量的URI我們稱為URI路徑模板。
@GET注解是一個請求方法指示符。在上面的例子中,被注解的Java方法會處理HTTP GET請求。
@Produces注解用來指定資源能夠生產和發送回客戶端的MIME媒體類型。在上面的例子中,Java方法會生成MIME媒體類型“text/plain”。
@Consumes注解用來指定資源能夠消費的客戶端發送的MIME媒體類型。我們可以將上面的例子中的代碼修改為
- @POST
- @Consumes("text/plain")
- public void postClichedMessage(String message) {
- // Store the message
- }
@Path注解和URI路徑模板
@Path注解指定了URI資源會響應的路徑模板,是指定在資源的類級別或方法級別上。@Path注解的值是一個相對URI路徑模板,這個路徑是相對於資源發布的服務器的基礎URI路徑、應用程序的上下文根路徑和JAX-RS運行時響應的URL。URI路徑模板是包含變量的URI。這些變量在運行時會被取代,這樣資源就能夠根據被取代的URI來響應請求。變量是用花括號{}表示的,例如下面的例子
- @Path annotation:
- @Path("/users/{username}")
在這個例子中,用戶會被提示輸入自己的名字,然后一個被配置來響應這個URI路徑模板的JAX-RS web service會響應該請求。例如,如果用戶輸入的名字是Galileo,這個web service會響應下面的URLhttp://example.com/users/Galileo.
要獲取用戶的名字,可以在請求方法的參數中使用@PathParam注解,如下面的代碼所示:
- @Path("/users/{username}")
- public class UserResource {
- @GET
- @Produces("text/xml")
- public String getUser(@PathParam("username") String userName) {
- ...
- }
- }
缺省的,URI變量必須符合正則表達式“[^/]+?”。開發人員也可以通過在變量名稱后指定不同的正則表達式來指定客戶化的變量模式。例如,如果用戶名字必須是由大寫或小寫字母組成,可以在變量的定義中指定:
- @Path("users/{username: [a-zA-Z][a-zA-Z_0-9]}")
在這個例子中,username這個變量只能匹配由大寫或小寫字母開頭,后跟0個或多個字母、數字和下划線的用戶名。如果用戶名不匹配這個模板,那么一個404(Not Found)響應會被發送給客戶端。
@Path的值並不要求必須以/開始。無論是否以/開頭或者開頭是否有空格,JAX-RS運行時會一樣的解析。
一個URI路徑模板可以包含一個或多個變量名,每個變量名都以前花括號{開始,以后花括號}結束。在上面的例子中,變量名是username。在運行時,被配置為響應上面的URI路徑模板的資源會處理URI數據,將URI中對應{username}的部分作為username的變量數據。
例如,如果你想要發布一個資源來響應URI路徑模板http://example.com/myContextRoot/resources/{name1}/{name2}/,你需要將應用程序發布在一個Java EE服務器上,該服務器要響應對URI http://example.com/myContextRoot的請求,並使用如下的@Path注解來修飾你的資源:
- @Path annotation:
- @Path("/{name1}/{name2}/")
- public class SomeResource {
- ...
- }
在這個例子中,在web.xml文件中指定的JAX-RS輔助servlet的URLpattern是:
- <servlet-mapping>
- <servlet-name>My JAX-RS Resource</servlet-name>
- <url-pattern>/resources/*</url-pattern>
- </servlet-mapping>
在URI路徑模板中,一個變量名可以被使用多次。
如果變量的值中的字符和URI的保留字符沖突,那么該沖突的字符應該使用百分號編碼代替。例如,變量值中的空格應該是一%20代替。
下表中列出了一些URI路徑模板的例子以及這些URI中的變量被替換后的結果,例子中使用保額變量名和值如下:
name1: james
name2: gatz
name3:
location: Main%20Street
question: why
注意:names的值是空字符串“”。
URI路徑模板 |
替換后的URI |
http://example.com/{name1}/{name2}/ |
http://example.com/james/gatz/ |
http://example.com/{question}/{question}/{question}/ |
http://example.com/why/why/why/ |
http://example.com/maps/{location} |
http://example.com/maps/Main%20Street |
http://example.com/{name3}/home/ |
http://example.com//home |
對HTTP資源的響應
資源的行為是由資源響應的HTTP方法(GET,POST,PUT,DELETE)來決定的。
請求方法指示符注解
請求方法指示符注解是由JAX-RS定義的運行時注解,對應同名的HTTP方法。在一個資源類文件中,HTTP方法通過使用請求方法指示符注解映射到Java編程語言的方法。一個資源的行為是由其要響應的HTTP方法決定的。JAX-RS為普通的HTTP方法定義了@GET,@POST,@PUT,@DELETE和@HEAD注解。開發人員也肯創建自己的客戶化的請求方法指示符。創建客戶化的請求方法指示符不在本教程的范圍內。
下面的例子是從storage service例子程序中抽取的,顯示了怎樣使用PUT方法來創建或更新storage容器:
- @PUT
- public Response putContainer() {
- System.out.println("PUT CONTAINER " + container);
- URI uri = uriInfo.getAbsolutePath();
- Container c = new Container(container, uri.toString());
- Response r;
- if (!MemoryStore.MS.hasContainer(c)) {
- r = Response.created(uri).build();
- } else {
- r = Response.noContent().build();
- }
- MemoryStore.MS.createContainer(c);
- return r;
- }
缺省的,如果沒有顯示的實現對應的方法,JAX-RS運行時會自動的支持HEAD方法和OPTIONS方法。對HEAD方法,運行時會調用實現了的GET方法並忽略response實體。對OPTIONS,響應頭Allow會被設置到資源支持的一組HTTP方法。另外,JAX-RS運行時會返回一個Web應用程序定義語言(WADL)文檔來描述資源。更多的信息見https://wadl.dev.java.net/。
由請求方法指示符修飾的方法必須返回void、Java編程語言的類型或javax.ws.rs.core.Response對象。可以使用PathParam或QueryParam注解來從URI中抽取多個參數,詳細描述見第246頁的“抽取request參數”。Java類型和實體段之間的轉換是實體提供者(如MessageBodyReader和MessageBodyWriter)的責任。
想要在response中提供額外的元數據方法應該返回一個Response類的實例。ResponseBuilder類使用builder模式提供了一個創建Response實例的簡便的方法。HTTP PUT和POST方法期望有HTTP request體,因此應該對響應PUT和POST請求的方法使用MessageBodyReader。
@PUT和@POST都能夠被使用來創建和更新資源。POST可以表示任何事情,因此在使用POST時,由應用程序來定義其語義。PUT有定義好的語義。當使用PUT來創建的時候,客戶聲明了新創建的資源的URI。
PUT有很明確的語義來創建和更新一個資源。客戶發送的表述必須是使用GET收到的同樣的表述,只是給出不同的媒體類型。PUT不允許一個資源被部分更新,這是使用PUT方法時的一個很常見的錯誤。一個通用的應用程序模式是使用POST類創建資源並返回一個201響應,將新創建的資源的URI的值設置為location頭。這種模式下,web service聲明了新創建的資源的URI。
使用實體提供者來映射HTTP Response和Request實體段
實體提供者提供了在表述和相關的Java類型之間的映射服務。兩種類型的實體提供者是MessageBodyReader和MessageBodyWriter。對於HTTP request,MessageBodyReader被用來將HTTP request實體段映射為方法參數。在response方面,使用MessageBodyWriter來將返回值映射為HTTP response實體段。如果應用程序需要提供附加的元數據,例如HTTP頭或不同的狀態碼,方法可以返回一個包裝了這些實體的Response實例,該實例可以用Response.ResponseBuilder創建。
下表顯示了自動支持的標准的類型,只有當不使用這些標准類型的時候才需要編寫實體提供者。
Java類型 |
支持的媒體類型 |
byte[] |
所有的媒體類型(*/*) |
java.lang.String |
所有的文本媒體類型(text/*) |
java.io.InputStream |
所有的媒體類型(*/*) |
java.io.Reader |
所有的媒體類型(*/*) |
java.io.File |
所有的媒體類型(*/*) |
javax.activation.DataSource |
所有的媒體類型(*/*) |
javax.xml.transform.Source |
XML媒體類型(text/xml,application/xml和application/*+xml) |
javax.xml.bind.JAXBElement和應用程序提供的JAXB類 |
XML媒體類型(text/xml,application/xml和application/*+xml) |
MultivaluedMap<String,String> |
表單內容(application/x-www-form-urlencoder) |
StreamingOutPut |
所有的媒體類型(*/*),只對MessageBodyWriter有效 |
下面的例子顯示了怎樣與@Consumes和@Provider注解一起使用MessageBodyReader:
- @Consumes("application/x-www-form-urlencoded")
- @Provider
- public class FormReader implements MessageBodyReader<NameValuePair> {
下面的例子顯示了怎樣與@Produces和@Provider注解一起使用MessageBodyWriter:
- @Produces("text/html")
- @Provider
- public class FormWriter implements
- MessageBodyWriter<Hashtable<String, String>> {
下面的例子顯示了怎樣使用ResponseBuilder:
- @GET
- public Response getItem() {
- System.out.println("GET ITEM " + container + " " + item);
- Item i = MemoryStore.MS.getItem(container, item);
- if (i == null)
- throw new NotFoundException("Item not found");
- Date lastModified = i.getLastModified().getTime();
- EntityTag et = new EntityTag(i.getDigest());
- ResponseBuilder rb = request.evaluatePreconditions(lastModified, et);
- if (rb != null)
- return rb.build();
- byte[] b = MemoryStore.MS.getItemData(container, item);
- return Response.ok(b, i.getMimeType()).
- lastModified(lastModified).tag(et).build();
- }
使用@Consumes和@Produces來客戶化Request和Response
發送給資源的信息和傳回客戶端的信息都被指定了MIME媒體類型,是在HTTP request或response的頭中指定的。可以使用下面的注解來指定資源能夠響應或生產的MIME媒體類型:
- javax.ws.rs.Consumes
- javax.ws.rs.Produces
默認的,一個資源能夠響應和生產所有的MIMIE媒體類型。
@Produces注解
注解@Produces是用來指定一個資源能夠產生並發送回客戶端的MIME媒體類型或表現。如果@Produces是應用在類級別上,那么默認的資源的所有的方法都能夠生產指定的MIME類型。如果是應用在方法級別上,那么這個注解會覆蓋應用在類級別的@Produces注解。如果資源中沒有方法能夠生產客戶端請求的MIME類型,那么JAX-RS運行時會發送回一個HTTP的“406 Not Acceptable”錯誤。
注解@Produces的值是一個MIME類型的字符串數組,例如
- @Produces({"image/jpeg,image/png"})
下面的例子顯示了怎樣在類級別和方法級別應用@Produces注解:
- @Path("/myResource")
- @Produces("text/plain")
- public class SomeResource {
- @GET
- public String doGetAsPlainText() {
- ...
- }
- @GET
- @Produces("text/html")
- public String doGetAsHtml() {
- ...
- }
- }
方法doGetAsPlainText()默認使用的是類級別上定義的@Produces注解指定的MIME媒體類型。方法doGetAsHtml上的@Produces注解覆蓋了類級別的設置,因此該方法能夠生成的是HTML類型,而不是普通文本。
如果一個資源類能夠生產超過一種MIME媒體類型,那么資源方法的選擇就對應最能夠接受的客戶端聲明的媒體類型。具體來說,HTTP請求的Accept頭屬性中聲明了最可接受的MIME類型。例如,如果Accept頭的值是Accept:text/plain,那么方法doGetAsPlainText會被調用。如果Accept頭的值是Accept:text/plain;q=0.9,text/html,這聲明了客戶端能夠接受媒體類型text/plain和test/html,但是更喜歡后者,因此doGetAsHtml方法會被調用。
一個@Produces注解中可以聲明多個媒體類型。下面的代碼例子顯示了怎樣做到這點:
- @Produces({"application/xml", "application/json"})
- public String doGetAsXmlOrJson() {
- ...
- }
當可接受的媒體類型是application/xml或application/json的時候這個doGetAsXmlOrJson方法會被調用。如果兩個媒體類型是同樣可接受的,那么會選擇聲明在前面的一個。
上面的例子中,為了更明白,我們使用的是明確的MIME媒體類型。也可以使用相應的常量值,這樣可以減少拼寫錯誤。相關的信息見MediaType類的常量字段,位於https://jsr311.dev.java.net/nonav/releases/1.0/javax/ws/rs/core/MediaType.html。
@Consumes注解
注解@Consumes被用來指定資源能夠接受或消費的來自客戶端的MIME媒體類型。如果@Consumes是應用在類級別上的,該類的所有的響應方法默認的接受指定的MIME類型。如果是應用在方法級別上,那么方法級別上的@Consumes注解會覆蓋應用在類級別上的@Consumes注解。
如果資源不能夠消費客戶請求中的MIME類型,JAX-RS運行時會發送回一個HTTP 415 (“Unsupported Media Type”)錯誤。
@Consumes注解的值是一個可接受的MIME類型的字符串數組。例如:
- @Consumes({"text/plain,text/html"})
下面的例子顯示了怎樣在類級別和方法級別上使用@Consumes注解。
- @Path("/myResource")
- @Consumes("multipart/related")
- public class SomeResource {
- @POST
- public String doPost(MimeMultipart mimeMultipartData) {
- ...
- }
- @POST
- @Consumes("application/x-www-form-urlencoded")
- public String doPost2(FormURLEncodedProperties formData) {
- ...
- }
- }
方法doPost默認的接受類級別的@Consumes注解指定的MIME類型。方法doPost2的@Consumes注解覆蓋了類級別的@Consumes注解,因此doPost2方法可接受的MIME類型是application/x-www-form-urencoded。
如果沒有任何的資源方法能夠響應請求中的MIME類型,那么一個HTTP 415錯誤會被返回給客戶端。
本節中前面討論的HelloWorld例子中,我們可以使用@Consume注解,如同我們下面的代碼所做的
- @POST
- @Consumes("text/plain")
- public void postClichedMessage(String message) {
- // Store the message
- }
在這個例子中,這個方法會消費由MIME媒體類型text/plain指定的表現。注意這里資源的方法返回的是void,這意味着沒有任何表現被返回,因此一個狀態碼為HTTP 204(“No Content”)的響應會被返回。
提取請求參數
資源方法的參數可能被添加了基於參數的注解來從請求中提取信息。在以前的例子中我們展現了時候@PathParam參數來從匹配@Path中聲明的路徑的request的URL中提取路徑參數。
可以在資源類中提取下面類型的參數:
- Query
- URI Path
- Form
- Cookie
- Header
- Matrix
Query參數是從請求URI的查詢參數中抽取的,在方法參數中使用javax.ws.rs.QueryParam注解來指定。下面的代碼例子來自sparklines例子程序,演示了怎樣使用@QueryParam注解來從請求URL中抽取query參數:
- @Path("smooth")
- @GET
- public Response smooth(
- @DefaultValue("2") @QueryParam("step") int step,
- @DefaultValue("true") @QueryParam("min-m") boolean hasMin,
- @DefaultValue("true") @QueryParam("max-m") boolean hasMax,
- @DefaultValue("true") @QueryParam("last-m") boolean hasLast,
- @DefaultValue("blue") @QueryParam("min-color") ColorParam minColor,
- @DefaultValue("green") @QueryParam("max-color") ColorParam maxColor,
- @DefaultValue("red") @QueryParam("last-color") ColorParam lastColor
- ) { ... }
如果query參數step在請求URI的查詢部分中存在,那么將從URI中抽取step的值並將其解析為32位的有符號整數並賦值給方法參數step。如果在請求URI的查詢部分中不存在step參數,那么@DefaultValue注解所聲明的缺省值2將被賦給方法參數step。如果step參數在請求URI中存在,但是無法被解析為32位的符號整數,那么一個HTTP 400(“Client Error”)響應將會被返回。
用戶自定義的Java編程語言類型也可以被用來作為query參數。下面的代碼例子是上面的例子中使用的ColorParam類。
- public class ColorParam extends Color {
- public ColorParam(String s) {
- super(getRGB(s));
- }
- private static int getRGB(String s) {
- if (s.charAt(0) == ’#’) {
- try {
- Color c = Color.decode("0x" + s.substring(1));
- return c.getRGB();
- } catch (NumberFormatException e) {
- throw new WebApplicationException(400);
- }
- } else {
- try {
- Field f = Color.class.getField(s);
- return ((Color)f.get(null)).getRGB();
- } catch (Exception e) {
- throw new WebApplicationException(400);
- }
- }
- }
- }
類ColorParam的構造方法接受一個String作為參數。
@QueryParam和@PathParam都只能被應用到以下的Java類型:
- 除char之外的原始類型
- 除Character之外的原始類型封裝類
- 有接受單獨的字符串做參數的構造函數的類
- 包含名為valueOf(String)的靜態方法的類
- List<T>,Set<T>,SortedSet<T>,這里T是上面所列的類型之一。有時候,同一個名字的參數可能包含多個值,在這種情況下,使用這些類型可以獲取所有的值
如果@DefaultValue沒有被使用,在請求中又沒有找到相應的query參數,那么對List,Set和SortedSet類型的參數其值是空的collection,對其他的對象類型值為null,對原始類型則是各自的默認值。
URI路徑參數是從request的URI中提取的,參數的名字對應類級別的@Path注解指定的URI路徑模板中的變量名。在方法參數中使用javax.ws.rs.PathParam注解來指定URI路徑參數。下面的例子顯示了怎樣使用@Path注解和在方法中使用@Path注解:
- @Path("/{username}")
- public class MyResourceBean {
- ...
- @GET
- public String printUsername(@PathParam("username") String userId) {
- ...
- }
- }
在這個例子中,URI路徑模板的變量名為username,該變量被指定為printUserName方法的參數。@PathParam注解的值被設置為變量名username。在運行的時候,printUserName被調用之前,username的值被從URI中提取出來並轉換成字符串。轉換的結果對printUserName方法生效並作為userId變量。
如果路徑模板的變量無法被轉換成指定的類型,JAX-RS運行時會返回一個HTTP 400(“Bad Request”)錯誤給客戶端。如果@PathParam注解不能轉換成指定的類型,JAX-RS運行時會返回一個HTTP 404(“Not Found”)錯誤給客戶端。
@PathParam參數和其他的基於參數的注解(@MatrixParam,@HeaderParam,@CookieParam和@FormParam)遵守和@Query相同的規則。
Cookie參數是使用javax.ws.rs.CookieParam注解的參數,這種參數會從cookie相關的HTTP頭聲明的cookie中提取信息。Header參數是使用javax.ws.rs.HeaderParam注解的參數,這種參數從HTTP頭中提取信息。Matrix參數是使用javax.ws.rs.MatrixParam的參數,這種參數會從URL路徑段中提取信息。Form參數是使用javax.ws.rs.FormParam的參數,這種參數從MIME類型是application/x-www-form-urlencoded的請求表現中提取信息並遵從HTML表單指定的編碼,如同http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1描述的一樣。這種類型的參數對從以POST方式發送的HTML表單中提取信息很有用。
下面的例子中我們從POST的表單數據中提取name參數:
- @POST
- @Consumes("application/x-www-form-urlencoded")
- public void post(@FormParam("name") String name) {
- // Store the message
- }
要獲得所有的query或path參數的參數名稱和值的Map,使用如下的代碼:
- @GET
- public String get(@Context UriInfo ui) {
- MultivaluedMap<String, String> queryParams = ui.getQueryParameters();
- MultivaluedMap<String, String> pathParams = ui.getPathParameters();
- }
下面的方法獲得header參數和cookie參數的名稱和值的Map:
- @GET
- public String get(@Context HttpHeaders hh) {
- MultivaluedMap<String, String> headerParams = ui.getRequestHeaders();
- Map<String, Cookie> pathParams = ui.getCookies();
- }
通常,@Context被用來獲取和request或response相關的上下文的Java類型。
對form參數,我們可以進行以下的操作:
- @POST
- @Consumes("application/x-www-form-urlencoded")
- public void post(MultivaluedMap<String, String> formParams) {
- // Store the message
- }