- 浏览: 990670 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
运乃强谦:
老哥,你确定这个wsdl 地址 可以访问?
[CXF] Server与Client实现方式五:HTTPS -
wangyudong:
由CXF实现的微服务需要有比较好的工具去测试RESTful A ...
[CXF] Server与Client实现方式四:JMS -
dengmiao:
JAXB学习三 (验证) -
panamera:
你好。可以提供maven pom配置是怎么配置的?不知道你使用 ...
[CXF] Server与Client实现方式四:JMS -
u010221220:
请问楼主一二三部分的代码都应该放在哪个函数体中。
使用JDI监听Java程序运行
JAX-RS与Conneg
JAX-RS有一些用来帮助用户管理他的conneg的工具:
- 基于Accept头的方法派发
- 允许直接查看内容信息
- 用于处理多约束条件的APIs
1. 方法派发
前几节中,我们看到怎么使用@Produces注释来指示响应的Media Type。 JAX-RS也使用这个注释来分发请求到恰当的方法上,通过匹配最佳的请求的Accept头信息的Media Type 列表到由@Produces标注的元数据。例如:
@Path("/customers") public class CustomerResource { @GET @Path("{id}") @Produces("application/xml") public Customer getCustomerXml(@PathParam("id") int id) {...} @GET @Path("{id}") @Produces("text/plain") public String getCustomerText(@PathParam("id") int id) {...} @GET @Path("{id}") @Produces("application/json") public Customer getCustomerJson(@PathParam("id") int id) {...} }
这里三个方法对应的服务路径一样,但是@Produces的元数据不同。JAX-RS会基于请求信息的Accept头信息来选择恰当的处理方法,例如:
GET http://example.com/customers/1 Accept: application/json;q=1.0, application/xml;q=0.5
根据头一节的介绍,这里,Accept的数据类型的优先级为:
- application/json
- application/xml
因此对这个请求,getCustomerJson()方法将被调用。
2. JAXB与Conneg
之前的章节里介绍了怎么通过使用JAXB来实现从java对象到xml或者json的映射。而通过在JAX-RS中使用conneg,我们也可以实现一个可以服务于这两种格式的方法,例如:
@Path("/service") public class MyService { @GET @Produces({"application/xml", "application/json"}) public Customer getCustomer(@PathParam("id") int id) {...} }
3. 复杂的内容协议
有时候,简单的Accept头与@Produces之间的映射可能不足以解决问题,服务于同一路径的不同的JAX-RS方法可能需要处理不同的Media Type、Language、Encoding等等。 不幸的是JAX-RS并没有提供类似于@ProduceLanguages或者@ProduceEncodings注释。相反,我们必须实现自己的头信息查找方法,或者是使用JAX-RS API管理复杂的Conneg。接下来分别介绍这两种方式。
> 查看Accept头
在之前的章节里介绍过javax.ws.rs.core.HttpHeaders接口。这个接口包含了预处理的与Http请求相关的Conneg信息:
public interface HttpHeaders { public List<MediaType> getAcceptableMediaTypes(); public List<Locale> getAcceptableLanguages(); ... }
getAcceptableMediaTypes()得到包含定义在HTTP请求的Accept头信息的Media Type列表,其中的项被解析成一个个javax.ws.rs.core.MediaType对象,并且这个列表已经是基于其中的"q"值(显式或隐式的)排序的。
getAcceptableLanguages()处理HTTP请求的Accept-Language头信息,其中的项已经被解析成一个个java.util.Locale对象。并且和上面的MediaType一样,已经是根据"q"值有序的了。
通过使用@javax.ws.rs.core.Context注释来注入HttpHeaders对象。例如:
@Path("/myservice") public class MyService { @GET public Response get(@Context HttpHeaders headers) { MediaType type = headers.getAcceptableMediaTypes().get(0); Locale language = headers.getAcceptableLanguages().get(0); Object responseObject = ...; Response.ResponseBuilder builder = Response.ok(responseObject, type); builder.language(language); return builder.build(); } }
> variant处理
JAX-RS也提供了API用来处理当你有多个Media Type、Language或Encoding集的情况。通过使用javax.ws.rs.core.Request和javax.ws.rs.core.Variant类来处理这些复杂的匹配。首先看Variant类:
package javax.ws.rs.core.Variant public class Variant { public Variant(MediaType mediaType, Locale language, String encoding) {...} public Locale getLanguage() {...} public MediaType getMediaType() {...} public String getEncoding() {...} }
Variant类就是一个简单的包含Media Type,Language和Encoding的结构。它表示一个简单的你JAX-RS资源方法所支持的集合。然后通过在Request接口中设置一列这个类的对象来进行交互:
package javax.ws.rs.core.Request public interface Request { Variant selectVariant(List<Variant> variants) throws IllegalArgumentException; ... }
其中selectVariant()方法里设置的就是JAX-RS方法中支持的一列Variant对象。它会检查请求中的Accept、Accept-Language和Accept-Encoding头,然后把它们和Variant列表进行比较,找到最匹配的请求的Variant对象。如果没有符合的对象,则返回null。例如:
@Path("/myservice") public class MyService { @GET Response getSomething(@Context Request request) { List<Variant> variants = new ArrayList(); variants.add(new Variant(new MediaType("application/xml"),"en", "deflate")); variants.add(new Variant(new MediaType("application/xml"),"es", "deflate")); variants.add(new Variant(new MediaType("application/json"),"en", "deflate")); variants.add(new Variant(new MediaType("application/json"),"es", "deflate")); variants.add(new Variant(new MediaType("application/xml"),"en", "gzip")); variants.add(new Variant(new MediaType("application/xml"),"es", "gzip")); variants.add(new Variant(new MediaType("application/json"),"en", "gzip")); variants.add(new Variant(new MediaType("application/json"),"es", "gzip")); // Pick the variant Variant v = request.selectVariant(variants); Object entity = ...; // get the object you want to return ResponseBuilder builder = Response.ok(entity); builder.type(v.getMediaType()).language(v.getLanguage()).header("Content-Encoding", v.getEncoding()); return builder.build(); } }
这里花了很多代码去提供所支持的Variant。也有更好的方法去做自动选择,JAX-RS提供了javax.ws.rs.core.Variant.VariantBuilder类用来创建这些复杂的选择器:
public static abstract class VariantListBuilder { public static VariantListBuilder newInstance() {...} public abstract VariantListBuilder mediaTypes(MediaType... mediaTypes); public abstract VariantListBuilder languages(Locale... languages); public abstract VariantListBuilder encodings(String... encodings); public abstract List<Variant> build(); public abstract VariantListBuilder add(); }
它支持使用Builder的模式来创建variant列表。例如重写前面的例子:
@Path("/myservice") public class MyService { @GET Response getSomething(@Context Request request) { Variant.VariantBuilder vb = Variant.VariantBuilder.newInstance(); vb.mediaTypes(new MediaType("application/xml"), new MediaType("application/json")) .languages(new Locale("en"), new Locale("es")) .encodings("deflate", "gzip"); List<Variant> variants = vb.build(); // Pick the variant Variant v = request.selectVariant(variants); Object entity = ...; // get the object you want to return ResponseBuilder builder = Response.ok(entity); builder.type(v.getMediaType()) .language(v.getLanguage()) .header("Content-Encoding", v.getEncoding()); return builder.build(); } }
通过调用VariantBuilder的mediaTypes()、languages()和encodings()方法设置可能的值,最后调用build()方法,它会生成一个Variant列表,包含所有可能的组合。
VariantBuilder也支持多个不同的Variant集体,通过使用VariantBuilder.add()方法可以分隔和定义不同的Variant集。例如:
Variant.VariantBuilder vb = Variant.VariantBuilder.newInstance(); vb.mediaTypes(new MediaType("application/xml"),new MediaType("application/json")) .languages(new Locale("en"), new Locale("es")) .encodings("deflate", "gzip") .add() .mediaTypes(new MediaType("text/plain")) .languages(new Locale("en"), new Locale("es"), new Locale("fr")) .encodings("compress");
上例中VariantBuilder创建了两组Variant,最后builder后就是这两组的合集。
现实中使用Request.selectVariant()方法的例子并不多。首先,content encoding在JAX-RS并不是一个很容易处理的东西,如果你想灵活的处理content encoding,你最好是自己去处理所有的流。大多数JAX-RS的实现应该都自动支持了GZIP。
其次,多数JAX-RS的服务都会根据@Produces注释和Accept头信息自动处理响应的Media Type。
4. URI模式约定
Conneg是一个很强大的HTTP特性。问题是有的客户端,特别是浏览器并不支持它。例如Firefox浏览器的Accept头信息被硬编码为:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
如果你希望访问的是JSON数据,那可能就失败了。
一个常用的解决此类问题的方法就是把Conneg信息内嵌在URI中,而不是使用Accept头,例如:
/customers/en-US/xml/3323 /customers/3323.xml.en-US
内容信息以分隔的路径或文件名后缀被嵌在URI中。上例中,客户端要求的是XML格式,英文的信息。在JAX-RS中可以如下实现:
@Path("/customers/{id}.{type}.{language}") @GET public Customer getCustomer(@PathParam("id") int id, @PathParam("type") String type, @PathParam("language") String language) {...}
在JAX-RS规范完成之前,围绕着文件名后缀的使用确实被定义为规范的一部分。不幸的是,专业组不同意这个特性的整个语义定义,因此它还是被删除了。很多JAX-RS的实现仍然支持这个特性,因此了解它是怎么工作的还是很重要的。
规范定义和很多JAX-RS实现现在的工作方式是在文件后缀, Media Type和Language之间定义一个映射关系。xml后缀映射到application/xml;en后缀映射到en-US。当一个请求来了,JAX-RS实现就会提取后缀,并使用这个信息作为Conneg的数据,替换任何传入的Accept或Accept-Language头。例如:
@Path("/customers") public class CustomerResource { @GET @Produces("application/xml") public Customer getXml() {...} @GET @Produces("application/json") public Customer getJson() {...} }
如果请求为 GET /customers.json ,刚JAX-RS实现会提取.json后缀,并把它从请求路径中移除。然后它会查找匹配json的映射。假设是 application/json ,然后这个信息,而不是Accept头,不会被使用,最后getJson()方法就会被调用。
发表评论
-
【转】HTTP协议头部与Keep-Alive模式详解
2012-11-30 14:52 18241、什么是Keep-Alive模式? 我们知道HTTP协议采 ... -
JAX-RS入门 十三: JAX-RS与安全(Security)
2012-05-25 17:35 0网络安装包括以下几个方面: Anthentication( ... -
JAX-RS入门 十二: 可伸缩的JAX-RS应用
2012-05-25 17:27 3487一、HTTP Caching HTTP1.0中定义了E ... -
JAX-RS入门 十一:HATEOAS
2012-05-24 16:56 2511HATEOAS全称:超媒体即状态应用引擎 (Hypermedi ... -
JAX-RS入门 十: 兼容与演进
2012-05-07 16:05 2107网络服务会随着时间的 ... -
JAX-RS入门 九: 内容约定(1)
2012-05-04 11:04 3071通常一个SOA的应用都需要足够的灵活,以便于各种不同的客户端或 ... -
JAX-RS入门 八: HTTP响应
2012-04-27 15:31 29422首先先看一下HTTP中定义的响应码及其意义: ... -
JAX-RS入门 七: 数据处理(2)
2012-04-26 17:51 12955上节介绍了JAX-RS中怎么与一些基础的对象进行交互,这节介 ... -
JAX-RS入门 六: 数据处理(1)
2012-04-26 11:38 9008接下来要花两小节来介绍一下JAX-RS中的数据处理(Data ... -
JAX-RS入门 五: 自动类型转换
2012-04-25 11:24 5992一、默认类型转换规则 在上一节中,已经了解了怎么使用那 ... -
JAX-RS入门 四: 注入
2012-04-24 17:47 28792一、Annotations @javax.ws.rs.P ... -
JAX-RS入门 三 :细节
2012-04-24 13:48 9002一、若希望一个Java类能够处理REST请求,则这个类必须至少 ... -
JAX-RS入门 二 :运行
2012-04-20 17:37 20125上一节,已经成功的定义了一个REST服务,并且提供了具体的实现 ... -
JAX-RS入门 一 :基础
2012-04-20 15:04 78732简介 JAX-RS是一套用java实现REST服务的规范,提 ...
相关推荐
标题"jax-rs jax-ws所需包,亲测可用"表明这个压缩包包含了用于开发Java RESTful Web服务(JAX-RS)和Java SOAP Web服务(JAX-WS)所需的库文件。这些库是Java应用程序进行Web服务交互的核心组件,确保了对HTTP协议...
2. **实体序列化与反序列化**:JAX-RS默认支持JSON和XML格式的数据交换,通过`@Produces`和`@Consumes`注解指定响应或请求的数据类型。例如,`@Produces("application/json")`表示资源返回JSON格式的数据。 3. **...
[奥莱理] RESTful Java 开发 (Jax-RS 实现) (英文版) [奥莱理] RESTful Java with Jax-RS (E-Book) ☆ 图书概要:☆ Learn how to design and develop distributed web services in Java using RESTful ...
The RESTEasy workbook that follows provides step-by-step instructions for installing, configuring, and running several working JAX-RS examples, using the JBoss RESTEasy implementation of JAX-RS 2.0. ...
2. **服务器容器**:虽然JAX-RS是一个标准,但需要一个服务器容器来运行这些服务。在提供的标签中提到了Jetty,这是一个轻量级、嵌入式的HTTP服务器和Servlet容器。Jetty可以轻松地与JAX-RS实现(如Jersey或RESTEasy...
综上所述,JAX-WS和JAX-RS都是Java平台中处理Web服务的重要工具,但它们的侧重点不同。JAX-WS专注于SOAP协议的Web服务,而JAX-RS则面向RESTful风格的API设计。了解并熟练掌握这两个API,对于Java开发者来说,意味着...
2. **客户端**:客户端部分会展示如何使用JAX-WS的`javax.xml.ws.Service`类或JAX-RS的`Client` API来调用服务端提供的Web服务。对于JAX-WS,客户端可能会生成一个代理类来调用服务;对于JAX-RS,可以使用`Client`...
赠送jar包:jackson-jaxrs-json-provider-2.7.8.jar; 赠送原API文档:jackson-jaxrs-json-provider-2.7.8-javadoc.jar; 赠送源代码:jackson-jaxrs-json-provider-2.7.8-sources.jar; 赠送Maven依赖信息文件:...
JAX-RS,全称Java API for RESTful Web Services,是Java平台上的一个标准,用于构建RESTful风格的Web服务。REST(Representational State Transfer)是一种轻量级、基于HTTP协议的设计模式,常用于实现分布式系统中...
**标题:“JAX-RS 扩展”** **描述**: 在Java世界中,JAX-RS(Java API for RESTful Web Services)是用于构建RESTful Web服务的标准API。这篇博客文章(遗憾的是,链接不可用)可能探讨了如何通过扩展JAX-RS来...
2. **JAX-RS示例**:可能提供了一个或多个使用JAX-RS创建的REST服务示例,演示了如何定义资源类、处理HTTP请求和响应,以及如何与其他Java EE组件集成。 3. **Maven配置**:由于提到了"Maven build",所以这个资源...
**JAX-RS 开发实例:Bookkeeping** JAX-RS,全称为Java API for RESTful Web Services,是Java平台上的一个标准,用于构建RESTful Web服务。它为开发人员提供了一种简单、直观的方式来创建Web服务,这些服务可以...
2. **JAX-RS 规范**:JSR 311 和 JSR 339(JAX-RS 2.0)是两个重要的 JAX-RS 规范版本。JAX-RS 2.0 引入了更多功能,如类型安全的 PATH 参数、异步处理、支持 JSON-P 和 XML 数据绑定等。 3. **注解驱动**:JAX-RS ...
1. **集成方式**: 通常通过Spring的Servlet容器如Tomcat或Jetty来部署JAX-RS应用,Spring负责应用的上下文管理和依赖注入,JAX-RS处理REST接口。 2. **Spring REST**: 使用Spring MVC的`@RestController`注解创建...
Java Web服务,特别是JAX-RS(Java API for RESTful Web Services)和Apache CXF,是企业级应用程序中实现服务接口的重要技术。本教程将深入探讨如何在SSH(Spring、Struts、Hibernate)架构中集成Web服务,以及如何...
JAX-RS(Java™ API for RESTful Web Services)是Java平台上用于开发基于REST架构风格的Web服务的API。它是Java EE(Java Platform, Enterprise Edition)的一部分,也作为独立的JAX-RS Reference Implementation ...
JAX-RS(JSR 311)指的是Java API for RESTful Web Services,Roy Fielding也参与了JAX-RS的制订,他在自己的博士论文中定义了REST。对于那些想要构建RESTful Web Services的开发者来说,JAX-RS给出了不同于JAX-WS...
概述这是一个多模块项目,包含用于以下数据格式的基于Jackson的JAX-RS提供程序:(二进制JSON) (另一种二进制JSON) 提供程序实现特定数据格式的JAX-RS MessageBodyReader和MessageBodyWriter处理程序。...
《RESTful Java with JAX-RS 2.0》是一本专注于Java语言在构建RESTful服务方面的专著。作者Bill Burke以其在Java技术方面的深厚底蕴和对RESTful架构的深刻理解,引领读者深入理解并掌握JAX-RS 2.0标准。 书中首先...