标签:数字 overview let cookies contain 整数 options 正则 简化
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注解:
随后的几节中我们会详细描述这个例子中使用的注解。
@Path注解的值是一个相对的URI路径。在上面的例子中,这个Java类会放在/helloworld这个路径下。上面的例子中使用的是静态的URI路径,是最简单的例子。在URI中,我们可以包含变量,对于这样的包含变量的URI我们称为URI路径模板。
@GET注解是一个请求方法指示符。在上面的例子中,被注解的Java方法会处理HTTP GET请求。
@Produces注解用来指定资源能够生产和发送回客户端的MIME媒体类型。在上面的例子中,Java方法会生成MIME媒体类型“text/plain”。
@Consumes注解用来指定资源能够消费的客户端发送的MIME媒体类型。我们可以将上面的例子中的代码修改为
@Path注解和URI路径模板
@Path注解指定了URI资源会响应的路径模板,是指定在资源的类级别或方法级别上。@Path注解的值是一个相对URI路径模板,这个路径是相对于资源发布的服务器的基础URI路径、应用程序的上下文根路径和JAX-RS运行时响应的URL。URI路径模板是包含变量的URI。这些变量在运行时会被取代,这样资源就能够根据被取代的URI来响应请求。变量是用花括号{}表示的,例如下面的例子
在这个例子中,用户会被提示输入自己的名字,然后一个被配置来响应这个URI路径模板的JAX-RS web service会响应该请求。例如,如果用户输入的名字是Galileo,这个web service会响应下面的URLhttp://example.com/users/Galileo.
要获取用户的名字,可以在请求方法的参数中使用@PathParam注解,如下面的代码所示:
缺省的,URI变量必须符合正则表达式“[^/]+?”。开发人员也可以通过在变量名称后指定不同的正则表达式来指定客户化的变量模式。例如,如果用户名字必须是由大写或小写字母组成,可以在变量的定义中指定:
在这个例子中,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注解来修饰你的资源:
在这个例子中,在web.xml文件中指定的JAX-RS辅助servlet的URLpattern是:
在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容器:
缺省的,如果没有显示的实现对应的方法,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:
下面的例子显示了怎样与@Produces和@Provider注解一起使用MessageBodyWriter:
下面的例子显示了怎样使用ResponseBuilder:
使用@Consumes和@Produces来客户化Request和Response
发送给资源的信息和传回客户端的信息都被指定了MIME媒体类型,是在HTTP request或response的头中指定的。可以使用下面的注解来指定资源能够响应或生产的MIME媒体类型:
默认的,一个资源能够响应和生产所有的MIMIE媒体类型。
@Produces注解
注解@Produces是用来指定一个资源能够产生并发送回客户端的MIME媒体类型或表现。如果@Produces是应用在类级别上,那么默认的资源的所有的方法都能够生产指定的MIME类型。如果是应用在方法级别上,那么这个注解会覆盖应用在类级别的@Produces注解。如果资源中没有方法能够生产客户端请求的MIME类型,那么JAX-RS运行时会发送回一个HTTP的“406 Not Acceptable”错误。
注解@Produces的值是一个MIME类型的字符串数组,例如
下面的例子显示了怎样在类级别和方法级别应用@Produces注解:
方法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注解中可以声明多个媒体类型。下面的代码例子显示了怎样做到这点:
当可接受的媒体类型是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注解。
方法doPost默认的接受类级别的@Consumes注解指定的MIME类型。方法doPost2的@Consumes注解覆盖了类级别的@Consumes注解,因此doPost2方法可接受的MIME类型是application/x-www-form-urencoded。
如果没有任何的资源方法能够响应请求中的MIME类型,那么一个HTTP 415错误会被返回给客户端。
本节中前面讨论的HelloWorld例子中,我们可以使用@Consume注解,如同我们下面的代码所做的
在这个例子中,这个方法会消费由MIME媒体类型text/plain指定的表现。注意这里资源的方法返回的是void,这意味着没有任何表现被返回,因此一个状态码为HTTP 204(“No Content”)的响应会被返回。
提取请求参数
资源方法的参数可能被添加了基于参数的注解来从请求中提取信息。在以前的例子中我们展现了时候@PathParam参数来从匹配@Path中声明的路径的request的URL中提取路径参数。
可以在资源类中提取下面类型的参数:
Query参数是从请求URI的查询参数中抽取的,在方法参数中使用javax.ws.rs.QueryParam注解来指定。下面的代码例子来自sparklines例子程序,演示了怎样使用@QueryParam注解来从请求URL中抽取query参数:
如果query参数step在请求URI的查询部分中存在,那么将从URI中抽取step的值并将其解析为32位的有符号整数并赋值给方法参数step。如果在请求URI的查询部分中不存在step参数,那么@DefaultValue注解所声明的缺省值2将被赋给方法参数step。如果step参数在请求URI中存在,但是无法被解析为32位的符号整数,那么一个HTTP 400(“Client Error”)响应将会被返回。
用户自定义的Java编程语言类型也可以被用来作为query参数。下面的代码例子是上面的例子中使用的ColorParam类。
类ColorParam的构造方法接受一个String作为参数。
@QueryParam和@PathParam都只能被应用到以下的Java类型:
如果@DefaultValue没有被使用,在请求中又没有找到相应的query参数,那么对List,Set和SortedSet类型的参数其值是空的collection,对其他的对象类型值为null,对原始类型则是各自的默认值。
URI路径参数是从request的URI中提取的,参数的名字对应类级别的@Path注解指定的URI路径模板中的变量名。在方法参数中使用javax.ws.rs.PathParam注解来指定URI路径参数。下面的例子显示了怎样使用@Path注解和在方法中使用@Path注解:
在这个例子中,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参数:
要获得所有的query或path参数的参数名称和值的Map,使用如下的代码:
下面的方法获得header参数和cookie参数的名称和值的Map:
通常,@Context被用来获取和request或response相关的上下文的Java类型。
对form参数,我们可以进行以下的操作:
标签:数字 overview let cookies contain 整数 options 正则 简化
原文地址:http://www.cnblogs.com/ydxblog/p/7993991.html