Web服务学习笔记


apache cxf

With so many options available todevelopers today in the web services space, one of the questions worth askingis why should I use CXF? In no particular order, here are some of the reasonsyou might want to use CXF:

JAX-WS Support

CXF implements the JAX-WS APIs which makebuilding web services easy. JAX-WS encompasses many different areas:

  • Generating WSDL from Java classes and generating Java classes from WSDL
  • Provider API which allows you to create simple messaging receiving server endpoints
  • Dispatch API which allows you to send raw XML messages to server endpoints
  • Much more...

Spring Integration

Spring is a first class citizen with ApacheCXF. CXF supports the Spring 2.0 XML syntax, making it trivial to declareendpoints which are backed by Spring and inject clients into your application.

Aegis Databinding

Aegis Databinding(2.0.x) is our own databinding library that makes development ofcode-first web services incredibly easy. Unlike JAXB, you don't needannotations at all. It also works correctly with a variety of datatypes such asLists, Maps, Dates, etc. right out of the box. If you're building a prototypeweb services that's really invaluable as it means you have to do very littlework to get up and running (and one of the primary reasons XFire was started awhile back)

RESTful services

CXF enables the development of RESTfulservices via annotations using the HTTP Binding. Using URI templates and annotations you can bind a serviceoperation to arbitrary URL/verb combinations. For instance, you can annotate agetCustom method with @Get @HttpResource("/customers/{id}"). CXF willthen listen for GET requests on that URL and using the parameter at the {id}location as a parameter to the service.

WS-* Support

CXF supports a variety of web servicespecifications including WS-Addressing, WS-Policy, WS-ReliableMessaging andWS-Security.

Apache Licensed

CXF comes under the liberal Apache license, making CXF great for all types of applications.

 

文章一

REST 是一种软件架构模式,只是一种风格,不是像SOAP 那样本身承载着一种消息协议,也可以叫做REST 是基于HTTP协议的软件架构。

     REST 中重要的两个概念就是资源定位和资源操作,而HTTP协议恰好完整的提供了这两个要点,HTTP 协议中的URI 可以完成资源定位,GETPOSTOPTION等方法可以完成资源操作,因此REST 完全依赖HTTP 协议就可以完成Web服务,而不像SOAP 协议那样只利用HTTP 的传输特性,定位与操作由SOAP 协议自身完成,也正是由于SOAP 消息的存在,使得SOAP 笨重。你也可以说REST 充分利用了HTTP 协议的特性,而不是像SOAP 那样只利用了其传输这一特性(事实上大多数人提到HTTP 协议就只会想到它能用于数据传输)。

REST 是一种软件架构理念,现在被移植到Web 服务上(因此不要提到REST 就马上想到WebServiceJAX-RS 只是将REST 设计风格应用到Web服务开发),那么在开发Web 服务上,偏于面向资源的服务适用于REST,偏于面向活动的服务。另外,REST 简单易用,效率高,SOAP 成熟度较高,安全性较好。REST 提供的网络服务叫做OpenAPI,它不仅把HTTP 作为传输协议,也作为处理数据的工具,可以说对HTTP 协议做了较好的诠释,充分体现了HTTP 技术的网络能力。目前GoogleAmazon、淘宝都有基于REST OpenAPI 提供调用。

 

 

      WebService,JAX-RS只是将REST 设计应用到Web 服务开发.JAX-RS提供对了REST的支持

 

我们先看看具体的例子

1、接口类

 

 

Java代码  

1.  @Path("/rest_HelloWorld")  

2.  public interface Rest_HelloWorld {  

3.    

4.    

5.      @GET   

6.      @Produces (MediaType.TEXT_PLAIN)   

7.      @Path("/say/{name}")   

8.      public String say(@PathParam("name")String name);  

9.        

10.     @GET   

11.     @Produces (MediaType.TEXT_PLAIN)   

12.     @Path("/sayHello/{name}")   

13.     public String sayHello(@PathParam("user")User user);  

14.       

15.     @GET   

16.     @Produces ({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})   

17.     @Path("/getList/{id}")   

18.     public List<User> getList(@PathParam("id")Long id);  

19.       

20. }

21.    

 

 

   CXFRest使用的JAX-RS规范。JAX-RS: Java API for RESTful Web Services是一个Java编程语言应用程序接口,支持按照 表象化状态转变 (REST)架构风格创建Web服务Web服务.JAX-RS使用了JavaSE 5引入的Java 标注来简化Web服务客户端和服务端的开发和部署。

 

JAX-RS提供了一些标注将一个资源类,一个POJOJava类,封装为Web资源。标注包括:

1)、@Path,标注资源类或方法的相对路径

2)、@GET@PUT@POST@DELETE,标注方法是用的HTTP请求的类型

3)、@Produces,标注返回的MIME媒体类型,(注解标注,这个注解可以包含一组字符串,默认值是*/*,它指定REST 服务的响应结果的MIME类型,例如:application/xmlapplication/jsonimage/jpeg 等),你                    也可以同时返回多种类型,但具体生成结果时使用哪种格式取决于ContentTypeCXF 默认返回的是JSON 字符串。

4)、@PathParam@QueryParam@HeaderParam@CookieParam@MatrixParam@FormParam,分别标注方法的参数来自于HTTP请求的不同位置,例如@PathParam来自于URL的路径,@QueryParam来自于URL的查询参数,@HeaderParam来自于HTTP请求的头信息,@CookieParam来自于HTTP请求的Cookie

 

 

注意:前两章说的CXFspring整合及 都是使用JAX-WS规范。JAX-WS规范是一组XMLweb servicesJAVA APIjaxws 是配置SOAP方式的Web 服务

 

 

Spring中引入了两个新的名称空间jaxwsjaxrs,因为CXF 实现了Spring NamespaceHandler 接口,实现这个接口可以在Spring 中增加额外的配置。那么jaxws 自然是配置SOAP 方式的Web服务,你可以看到有jaxws:serverjaxws:endpointjaxws:client 三个元素,jaxws:server jaxws:endpoint 是等效的,都用于发布Web 服务,出现jaxws:endpoint 的原因是JAX-WS 规范中使用EndPoint发布Web 服务(前面使用过这种

方式),CXF 为了和JAX-WS 对应,提供了这个与jaxws:server功能一样的配置元素;

jaxrsREST 方式的Web服务,有jaxrs:serverjaxrs:client 两个元素。

 

2、接口实现类

 

 

Java代码  

1.  @Service("rest_HelloWorldImpl")  

2.  public class Rest_HelloWorldImpl implements Rest_HelloWorld {  

3.    

4.      public String say(String name) {  

5.              return name+",您好!";  

6.      }  

7.    

8.      public String sayHello(User user) {  

9.          return user.getName()+",您好!";  

10.     }  

11.       

12.     public List<User> getList(Long id){  

13.         List<User> list = new ArrayList<User>();  

14.           

15.         Long sid=1L;  

16.         User user = new User(sid,"张三"+sid,21);  

17.         list.add(user);  

18.           

19.         sid=2L;  

20.         user = new User(sid,"张三"+sid,21);  

21.         list.add(user);  

22.           

23.         sid=3L;  

24.         user = new User(sid,"张三"+sid,21);  

25.         list.add(user);  

26.         return list;  

27.     }  

28. }  

 

 

3CXFSpring中的配置

 

 

Java代码  

1.  <?xml version="1.0" encoding="UTF-8"?>  

2.  <beans xmlns="http://www.springframework.org/schema/beans"  

3.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

4.      xmlns:jaxws="http://cxf.apache.org/jaxws"  

5.      xmlns:jaxrs="http://cxf.apache.org/jaxrs"  

6.      xsi:schemaLocation=" http://www.springframework.org/schema/beans                       

7.                      http://www.springframework.org/schema/beans/spring-beans.xsd                         

8.                      http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd  

9.                      http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">  

10.     <import resource="classpath:META-INF/cxf/cxf.xml" />  

11.     <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />  

12.     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  

13.       

14.   

15.     <bean id="inMessageInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />  

16.     <bean id="outMessageInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>  

17.   

18.    <!--id:名称(随意配),implementor:指定接口具体实现类,address:随意配-->  

19.     <jaxws:endpoint id="helloWorld"  implementor="#HelloWorldImpl" address="/HelloWorld"  >  

20.         <!-- 输入日志拦截器 -->  

21.        <jaxws:inInterceptors>  

22.             <ref bean="inMessageInterceptor"/>  

23.        </jaxws:inInterceptors>  

24.        <!-- 输出日志拦截器 -->  

25.        <jaxws:outInterceptors>  

26.           <ref bean="outMessageInterceptor"/>  

27.        </jaxws:outInterceptors>  

28.        <jaxws:properties>  

29.           <entry key="mtom_enabled" value="true"></entry>  

30.        </jaxws:properties>  

31.     </jaxws:endpoint>  

32.       

33.     <jaxrs:server id="rest_HelloWorld" address="/">  

34.         <jaxrs:inInterceptors>  

35.            <ref bean="inMessageInterceptor"/>  

36.         </jaxrs:inInterceptors>  

37.         <jaxrs:outInterceptors>  

38.             <ref bean="outMessageInterceptor"/>  

39.         </jaxrs:outInterceptors>  

40.         <jaxrs:serviceBeans>  

41.             <ref bean="rest_HelloWorldImpl" />  

42.         </jaxrs:serviceBeans>  

43.         <jaxrs:extensionMappings>  

44.             <entry key="json" value="application/json" />  

45.             <entry key="xml" value="application/xml" />  

46.         </jaxrs:extensionMappings>  

47.         <jaxrs:languageMappings>  

48.             <entry key="en" value="en-gb" />  

49.         </jaxrs:languageMappings>  

50.     </jaxrs:server>  

51.   

52.     <!-- WebService 客户端 spring 配置文件cxf与Spring集成,cxf里提供了一个工厂类org.apache.cxf.jaxws.JaxWsProxyFactoryBean,  

53.     可以方便实现的调用WebService。serviceClass属性是接口类,address是webService的路径在其他bean里如果要调用webservice,  

54.     只要将client这个bean注入到需要使用的bean里。-->  

55.     <bean id="client" class="com.exp.service.outer.HelloWorld" factory-bean="clientFactory" factory-method="create" />  

56.     <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">  

57.         <property name="serviceClass" value="com.exp.service.outer.HelloWorld" />  

58.         <property name="address" value="http://localhost:8080/demo/webservice/HelloWorld" />  

59.     </bean>  

60. </beans>  

 

 

 

注意:以下代码是新增加代码

     xmlns:jaxrs="http://cxf.apache.org/jaxrs"

 

       http://cxf.apache.org/jaxrshttp://cxf.apache.org/schemas/jaxrs.xsd

 

 

Java代码  

1.  <jaxrs:server id="rest_HelloWorld" address="/">  

2.          <jaxrs:inInterceptors>  

3.             <ref bean="inMessageInterceptor"/>  

4.          </jaxrs:inInterceptors>  

5.          <jaxrs:outInterceptors>  

6.              <ref bean="outMessageInterceptor"/>  

7.          </jaxrs:outInterceptors>  

8.          <jaxrs:serviceBeans>  

9.              <ref bean="rest_HelloWorldImpl" />  

10.         </jaxrs:serviceBeans>  

11.         <jaxrs:extensionMappings>  

12.             <entry key="json" value="application/json" />  

13.             <entry key="xml" value="application/xml" />  

14.         </jaxrs:extensionMappings>  

15.         <jaxrs:languageMappings>  

16.             <entry key="en" value="en-gb" />  

17.         </jaxrs:languageMappings>  

18.     </jaxrs:server>  

 

 

4、访问

    http://localhost:8080/demo/webservice/rest_HelloWorld/getList/1

 

返回JSON格式: http://localhost:8080/demo/webservice/rest_HelloWorld/getList/1?_type=json

返回XML格式: http://localhost:8080/demo/webservice/rest_HelloWorld/getList/1?_type=xml

 

得到结果

 

Java代码  

1.  <Users>  

2.  <User>  

3.  <id>1</id>  

4.  <name>张三1</name>  

5.  <age>21</age>  

6.  </User>  

7.  <User>  

8.  <id>2</id>  

9.  <name>张三2</name>  

10. <age>21</age>  

11. </User>  

12. <User>  

13. <id>3</id>  

14. <name>张三3</name>  

15. <age>21</age>  

16. </User>  

17. </Users>  

 

 

使用CXFrest还需要额外增加一个Jarjsr311-api-1.1.1.jar

为了支持返回JSON格式,还需要jettison-1.1.jar

 

文章二

简介

JAX-RS (JSR-311) 是为 Java EE 环境下的 RESTful 服务能力提供的一种规范。它能提供对传统的基于 SOAP  Web 服务的一种可行替代。

在本文中,了解 JAX-RS 的主要组件。本文用一个例子展示了一个企业如何使用 JAX-RS 内的功能以一种 Restful 的方式公开员工的联系信息。

背景

多年来,开发人员使用各种工具在其 Java 应用程序内创建 RESTful 服务。由于 REST 架构的简单性,主要需求接收 HTTP 消息和头部的能力 — 可以由一个简单的 Java Web 容器实现。

Java servlets 常被用来开发 RESTful 应用程序。如何使用 servlet 并没有固定的模式。通常,servlet 会接受请求并自己解析这个 HTTP 请求 URI,以将此请求与一个已知资源相匹配。对于 REST 服务开发,这个简单的 servlet 模型以更为正式的 API 得到扩展。但是,因为这些 API 是在 servlet 模型之上开发的,所以这些 API 中没有一个是作为正式的标准开发的。

随着 REST 越来越多地被采用为一种架构,Java Community Process(JCP) 计划在未来的 JavaEnterprise Edition 6 发布版中包括对 REST 的正式支持。JSR-311 也已创建好,并已有了 JAX-RS 1.0 规范,提供了一种新的基于注释的方式来开发 RESTful服务。与 servlet 模型相比,JAX-RS 注释让您能集中于您的资源和数据对象。并且,您不必再开发通讯层(通过 servlet)。

Java 资源

JAX-RS 建立了一种特殊的语言来描述资源,正如由其编程模型所表示的。有五种主要条目:根资源、子资源、资源方法、子资源方法以及子资源定位

根资源

根资源是由 @Path 注释的 Java 类。@Path 注释提供了一个 value 属性,用来表明此资源所在的路径value 属性可以是文本字符、变量或变量外加一个定制的正则表达式。清单 1 给出了一个例子。


清单 1.JAX-RS 根资源

package com.ibm.jaxrs.sample.organization;import javax.ws.rs.Path;@Path(value="/contacts")public class ContactsResource {...}

 

子资源

子资源是作为 subresource locator 调用的结果返回的 Java 类。它们类似于根资源,只不过它们不是由 @Path 注释的,因它们的路径是由子资源定位器给出的。子资源通常包含由 HTTP 请求方法指示符(designator)注释的方法以便服务此请求。如果它们不包含如此注释的方法,那么它们将会通过指派给合适的子资源定位器来进一步解析此资源处理请求。


清单 2.JAX-RS 子资源

package com.ibm.jaxrs.sample.organization;import javax.ws.rs.GET;public class Department {@GETpublic String getDepartmentName() {...}}

 

如上所示的清单 2 展示了由 ContactsResource.getContactDepartment 方法返回的子资源。在这个例子中,如果一个 HTTPGET 请求被发送给 /contact/{contactName}/department 路径,那么 Department 子资源内的 getDepartmentName 资源方法就会处理此请求。

资源方法

资源方法是根资源或子资源内绑定到 HTTP 方法的 Java 方法。绑定是通过诸如 @GET 这样的注释完成的。


清单 3.JAX-RS 资源方法

package com.ibm.jaxrs.sample.organization;import java.util.List;import javax.ws.rs.GET;import javax.ws.rs.Path;@Path(value="/contacts")public class ContactsResource {@GETpublic List<ContactInfo> getContacts() {...}}

 

在清单 3 的例子中,发送到 /contacts 路径的 HTTP GET 请求将会由 getContacts() 资源方法处理。

子资源方法

子资源方法非常类似于资源方法;惟一的区别是子资源方法也是由 @Path 注释的,此注释进一步限定了该方法的选择


清单 4.JAX-RS 子资源方法

package com.ibm.jaxrs.sample.organization;import java.util.List;import javax.ws.rs.GET;import javax.ws.rs.Path;@Path(value="/contacts")public class ContactsResource {@GETpublic List<ContactInfo> getContacts() {...}@GET@Path(value="/ids")public List<String> getContactIds() {...}}

 

在清单 4 中,发送到 /contacts/ids 路径的 HTTP GET 请求将会由 getContactIds() 子资源方法处理。

子资源定位器

子资源定位器是能进一步解析用来处理给定请求的资源的一些方法。它们非常类似于子资源方法,因它们具备一个 @Path 注释,但不具备 HTTP 请求方法指示符,比如 @GET 注释。


清单 5.JAX-RS 子资源定位器

package com.ibm.jaxrs.sample.organization;import java.util.List;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;@Path(value="/contacts")public class ContactsResource {@GETpublic List<ContactInfo> getContactss() {...}@GET@Path(value="/ids")public List<String> getContactIds() {...}@Path(value="/contact/{contactName}/department")public Department getContactDepartment(@PathParam(value="contactName")String contactName) {...}}

 

在上述例子中,对 /contact/{contactName}/department 路径的任何 HTTP 请求都将由 getContactDepartment 子资源定位器处理。 {contactName} 部分表明 contact 路径部分之后可以是任何合法 URL 值。

注释

本节将会探讨一些重要的注释及其使用。对于由 JAX-RS 规范提供的注释的完整列表,可以参考本文的 参考资料 部分给出的 JSR-311 链接

@Path

@Path 注释被用来描述根资源、子资源方法或子资源的位置。value 值可以包含文本字符、变量或具有定制正则表达式的变量。清单 6 的例子展示了 @Path 注释的主要应用。


清单 6.@Path 的使用

package com.ibm.jaxrs.sample.organization;import java.util.List;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;@Path(value="/contacts")public class ContactsResource {@GET@Path(value="/{emailAddress:.+@.+\\.[a-z]+}")public ContactInfo getByEmailAddress(@PathParam(value="emailAddress")String emailAddress) {...}@GET@Path(value="/{lastName}")public ContactInfo getByLastName(@PathParam(value="lastName") String lastName) {...}}

 

ContactsResource 类上的注释表明对 /contacts 路径的所有请求都将由 ContactsResource 根资源处理。getByEmailAddress 上的 @Path 注释则表明任何发送到 /contacts/{emailAddress} 的请求(其中 emailAddress 代表的是正则表达式 .+@.+\\.[a-z]+)都将由 getByEmailAddress 处理。

getByLastName 方法上的 @Path 注释指定了发送到 /contacts/{lastName} 路径的所有请求(其中 lastName 代表的是一个与getByEmailAddress 内的正则表达式不匹配的有效的 URL 部分)都将由 getByLastName 方法处理。

@GET@POST@PUT@DELETE@HEAD

@GET@POST@PUT@DELETE 以及 @HEAD 均是 HTTP 请求方法指示符注释。您可以使用它们来绑定根资源或子资源内的 Java 方法与 HTTP 请求方法。HTTP GET 请求被映射到由 @GET 注释的方法;HTTP POST 请求被映射到由 @POST 注释的方法,以此类推。用户可能还需要通过使用 @HttpMethod 注释定义其自己的定制 HTTP 请求方法指示符。


清单 7. 定制的 HTTP 请求方法指示符注释

package com.ibm.jaxrs.sample.organization;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import javax.ws.rs.HttpMethod;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@HttpMethod("GET")public @interface CustomGET {}

 

上述的声明定义了 @CustomGET 注释。此注释将具有与 @GET 注释相同的语义值并可用在其位置上。

@Conumes@Produces

@Consumes 注释代表的是一个资源可以接受的 MIME 类型。@Produces 注释代表的是一个资源可以返回的 MIME 类型。这些注释均可在资源、资源方法、子资源方法、子资源定位器或子资源内找到。


清单 8.@Consumes/@Produces

package com.ibm.jaxrs.sample.organization;import java.util.List;import javax.ws.rs.Consumes;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;import javax.ws.rs.Produces;@Path(value="/contacts")public class ContactsResource {@GET@Path(value="/{emailAddress:.+@.+\\.[a-z]+}")@Produces(value={"text/xml", "application/json"})public ContactInfo getByEmailAddress(@PathParam(value="emailAddress")String emailAddress) {...}@GET@Path(value="/{lastName}")@Produces(value="text/xml")public ContactInfo getByLastName(@PathParam(value="lastName") String lastName) {...}@POST@Consumes(value={"text/xml", "application/json"})public void addContactInfo(ContactInfo contactInfo) {...}}

 

对于上述的 getByEmailAddress  addContactInfo 方法,它们均能处理 text/xml  application/json。被接受或返回的资源表示将依赖于客户机设置的 HTTP 请求头。@Consumes 注释针对 Content-Type 请求头进行匹配,以决定方法是否能接受给定请求的内容

在清单 9 中,application/json  Content-Type 头再加上对路径 /contacts  POST,表明我们 ContactsResource 类内的 addContactInfo 方法将会被调用以处理请求。


清单 9.Content-Type 头部的使用

POST /contacts HTTP/1.1Content-Type: application/jsonContent-Length: 32

 

相反地,@Produces 注释被针对 Accept 请求头进行匹配以决定客户机是否能够处理由给定方法返回的表示。


清单 10.Accept 头部的使用

GET /contacts/johndoe@us.ibm.com HTTP/1.1Accept: application/json

 

在清单 10 中,对 /contacts/johndoe@us.ibm.com  GET 请求表明了 getByEmailAddress 方法将会被调用并且返回的格式将会是application/json,而非 text/xml

Providers

JAX-RS 提供程序是一些应用程序组件,允许在三个关键领域进行运行时行为的定制:数据绑定、异常映射以及上下文解析(比如,向运行时提供 JAXBContext 实例)。每个 JAX-RS 提供程序类必须 @Provider 注释。如下的例子讨论了两个数据绑定提供程序MessageBodyWriter  MessageBodyReader

MessageBodyWriter

MessageBodyWriters JAX-RS 运行时用来序列化所返回资源的表示。遵从 JSR-311的运行时提供了对常见类型(java.lang.Stringjava.io.InputStream JAXB 对象等)的本机支持,但用户也可以向 JAX-RS 运行时提供他或她自己的 MessageBodyWriter。比如,您可以提供一个定制 MessageBodyWriter 来处理定制 ContactInfo Java 类型,如下所示。


清单 11. 定制 MessageBodyWriter

package com.ibm.jaxrs.sample.organization;import javax.ws.rs.Consumes;import javax.ws.rs.Produces;import javax.ws.rs.ext.MessageBodyWriter;import javax.ws.rs.ext.Provider;@Provider@Produces("text/xml")public class ContactInfoWriter implements MessageBodyWriter<ContactInfo> {public long       getSize(T t, java.lang.Class<ContactInfo> type,java.lang.reflect.Type genericType, java.lang.annotation.Annotation[]annotations, MediaType mediaType) {...}public boolean isWriteable(java.lang.Class<ContactInfo> type,java.lang.reflect.Type genericType, java.lang.annotation.Annotation[]annotations, MediaType mediaType) {return true;}public void writeTo(ContactInfo contactInfo, java.lang.Class<ContactInfo> type,java.lang.reflect.Type genericType, java.lang.annotation.Annotation[]annotations, MediaType mediaType, MultivaluedMap<java.lang.String, java.lang.Object> httpHeaders, java.io.OutputStreamentityStream) {contactInfo.serialize(entityStream);}}

 

ContactInfoWriter 则在所返回的资源表示被序列化之前由 JAX-RS 运行时调用。如果 isWriteable 返回 true  @Produces 是此资源方法的 @Produces 值最为接近的匹配,就会调用 writeTo 方法。在这里,ContactInfoWriter 负责向底层的OutputStream 序列化 ContactInfo 实例的内容。

MessageBodyReader

MessageBodyReaders 则与 MessageBodyWriters 相反。对于反序列化,JAX-RS 运行时支持与序列化相同的类型。用户也可以提供他或她自己的 MessageBodyReader 实现。MessageBodyReader 的最主要的功能是读取请求 InputStream 并将传入的字节反序列化到一个此资源方法期望的 Java 对象。ContactInfo 类型的 MessageBodyReader 可以类似于清单 12

package com.ibm.jaxrs.sample.organization;import javax.ws.rs.Consumes;import javax.ws.rs.Produces;import javax.ws.rs.ext.MessageBodyReader;import javax.ws.rs.ext.Provider;@Provider@Consumes("text/xml")public class ContactInfoReader implements MessageBodyReader<ContactInfo> {public boolean isReadable(java.lang.Class<ContactInfo> type,java.lang.reflect.Type genericType, java.lang.annotation.Annotation[]annotations, MediaType mediaType) {return true;}public ContactInfo readFrom(java.lang.Class<ContactInfo> type,java.lang.reflect.Type genericType, java.lang.annotation.Annotation[]annotations, MediaType mediaType, MultivaluedMap<java.lang.String,java.lang.String> httpHeaders, java.io.InputStreamentityStream) {return ContactInfo.parse(entityStream);}}

 

MessageBodyWriter isWriteable 类似,ContactInfoReader  isReadable 方法将被调用以便决定MessageBodyReader 能否处理此输入。如果 isReadable 返回 true  @Consumes 值与此资源方法的 @Consumes 值最为匹配,就会选择ContactInfoReader。当 readFrom 方法被调用时,结果会是基于请求 InputStream 的内容创建 ContactInfo 实例。

配置

至此,我们探讨了 JAX-RS 资源类和一些提供程序类(MessageBodyReaders MessageBodyWriters)。那么,该如何在 JAX-RS 运行时内配置这些类呢?这可以通过扩展javax.ws.rs.core.Application 类实现。此类提供了一组类或一组单例(singleton)对象实例,在一个 JAX-RS 应用程序内包括所有的根级别的资源和提供程序(由 @Provider 注释的类)。若为这个示例联系信息应用程序扩展这个 Application 类,它应该类似于清单 13


清单 13.ContactInfoApplication

package com.ibm.jaxrs.sample.organization;import java.util.HashSet;import java.util.Set;import javax.ws.rs.core.Application;public class ContactInfoApplicaiton extends Application {public Set<Class<?>> getClasses() {Set<Class<?>> classes = new HashSetSet<Class<?>>();classes.add(ContactsResource.class);classes.add(ContactInfoWriter.class);classes.add(ContactInfoReader.class);}public SetSet<Object<?>> getSingletons() {// nothing to do, no singletons}}

 

getClasses 方法为 JAX-RS 运行时提供了一组可用于元数据的类。请注意getSingletons 方法什么都不返回。通常而言,将 JAX-RS 提供程序视为单例是没有问题的,但将一个 JAX-RS 资源视为单例则要格外谨慎。常被 JAX-RS 资源类使用的基于注释的注入可能在一个单例实例的情况内并不受支持。因此,除非仔细计划,否则应该避免使用 JAX-RS 资源的单例实例。

假设,您正在一个 servlet 容器内部署一个 JAX-RS 应用程序,有两种方法可以向 JAX-RS 运行时注册您的javax.ws.rs.core.Application 子类。这是由 WAR 文件 web.xml 处理的,如下所示。


清单 14. 不能感知 JAX-RS servlet 容器

<web-app version="2.5"xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><servlet><servlet-name>ContactInfoServlet</servlet-name><servlet-class>com.sample.RESTSystemServlet</servlet-class><init-param><param-name>javax.ws.rs.Application</param-name><param-value>com.ibm.jaxrs.sample.organization.ContactInfoApplication</param-value></init-param></servlet><servlet-mapping><servlet-name>ContactInfoServlet</servlet-name><url-pattern>/*</url-pattern></servlet-mapping></web-app>

 

在一个被认为是不能感知 JAX-RS servlet 容器内,应该作为 servlet 定义内的 init-param 提供 Application 子类名。init-param 的名字必须是 javax.ws.rs.Applicationservlet 类则很可能是 JAX-RS 运行时系统 servlet。您可以列出每个可能的 URL 模式,或者使用 /* 通配符注册,如下所示。


清单 15. 能感知 JAX-RS servlet 容器

<web-app version="2.5"xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><servlet><servlet-name>ContactInfoServlet</servlet-name><servlet-class>com.ibm.jaxrs.sample.organization.ContactInfoApplication</servlet-class></servlet><servlet-mapping><servlet-name>ContactInfoServlet</servlet-name><url-pattern>/*</url-pattern></servlet-mapping></web-app>

 

在一个被认为是能感知 JAX-RS servlet 容器内,必须作为 servlet 定义内的 servlet 类元素的值提供 Application 子类名。您仍然可以选择是列出每个可能的 URL 模式还是使用 /* 通配符注册。

Apache Wink 作为运行时的 JAX-RS

下一步是找到一个能够支持 JAX-RS 内的可用功能的运行时。Apache Wink 项目就提供了一个能满足这种要求的运行时,具有上面所述的所有特性(参见 参考资料)。起初,Wink 是由开源社区的多个厂商和成员发起的一个协作项目。该项目的目的是提供最为灵活和轻量级的运行时。

除了标准 JAX-RS 特性之外,Wink 还提供了对 JSONAtom  RSS 序列化格式的增强支持。JAX-RS 本身并不提供客户机 API,但 Wink 包括了其对客户机 API 的自身模型,并且是完全以资源为中心的。

为了简化基于 Wink 的服务的开发,可以下载 Wink 1.0 库并将它们作为默认 JAX-RS 库包括到 RationalApplication Developer (RAD) 7.5.5 开发环境(参见 参考资料)中。在这个更新版本中,RAD 添加了一个 JAX-RS facet,可供您进行配置以支持验证器和注释帮助。这个新的 facet 还能通过自动生成所需的 servlet 项和映射来简化 servlet 的配置。

结束语

与传统的 servlet 模型相比,JAX-RS 提供了一种可行的、更为简便、移植性更好的方式来在 Java 内实现 RESTful 服务。使用注释让您能够轻松提供 Java 资源的路径位置并将 Java 方法绑定到 HTTP 请求方法。一种可移植的数据绑定架构提供了一些本机的 Java 类型支持并允许进行序列化/反序列化处理的完全定制。javax.ws.rs.core. Application 子类的扩展以及 web.xml 内的相应清单表明了用最少的部署描述符配置就能进行轻松部署。

本文只涉及了 JAX-RS 所能提供功能的一部分。就提供应用程序上下文(比如 JAXBContext 实例)并将运行时异常映射给 HTTP 请求而言,其他两个 JAX-RS 提供程序类型 ContextResolvers  ExceptionMappingProviders 还能提供对应用程序组件的进一步控制。注释的定义是为了控制方法参数和类成员的注入,它们在运行时的整个过程向应用程序提供了有价值的上下文信息。总的来说,JAX-RS 必将是一种面向基于 Java RESTful 服务开发的简便、可移植的、全面的 API

 

文章三

[CXF] ServerClient实现方式一:JAXWS

博客分类: 

·        OpenSource

·        JAX-WS

 

【参考:http://cxf.apache.org/docs/jax-ws-configuration.html

一、SEI的定义

假设有以下SEI定义:

Java代码  

1.  @WebService  

2.  public interface OrderProcess {  

3.      public String processOrder(Order order);  

4.  }  

 (实现端省略)

 

二、Server端发布

则最简单的发布Server的方式可以如下:

 

Java代码  

1.  Endpoint.publish("http://localhost:8181/orderProcess"new OrderProcessImpl());  

 

或者是spring的方式:

Xml代码  

1.  <beans xmlns="http://www.springframework.org/schema/beans"  

2.      xmlns:jaxws="http://cxf.apache.org/jaxws"  

3.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  

4.      xsi:schemaLocation="  

5.         http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd  

6.         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  

7.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  

8.    

9.      <import resource="classpath:META-INF/cxf/cxf.xml" />  

10.     <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />  

11.     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  

12.   

13.     <jaxws:endpoint id="orderProcess"  

14.         implementor="com.liulutu.liugang.cxf.jaxws.OrderProcessImpl" address="http://localhost:8090/orderProcess" />  

15. </beans>  

 三、Client端调用

Java代码  

1.  Service service = Service.create(new URL("<wsdlfilepath>"),  

2.          new QName("namespace""servicename"));  

3.  OrderProcess port = orderProcessService.getPort(OrderProcess.class);  

4.  String s = port.processOrder(<arg>);  

5.  System.out.println(s);  

 或者Spring的方式:

Xml代码  

1.  <?xml version="1.0" encoding="UTF-8"?>  

2.  <beans xmlns="http://www.springframework.org/schema/beans"  

3.         xmlns:jaxws="http://cxf.apache.org/jaxws"  

4.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

5.         xsi:schemaLocation="  

6.            http://www.springframework.org/schema/beans   

7.            http://www.springframework.org/schema/beans/spring-beans.xsd  

8.            http://cxf.apache.org/jaxws   

9.            http://cxf.apache.org/schemas/jaxws.xsd">  

10.    

11.     <jaxws:client id="orderClient"  

12.                   serviceClass="com.liulutu.liugang.cxf.codefirst.OrderProcess"  

13.                   address="http://localhost:8181/orderProcess" />  

14. </beans>  

 然后在java代码里:

Java代码  

1.  ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext(  

2.        "/META-INF/spring/jaxwsspringclient.xml");  

3.  OrderProcess bean = xmlApplicationContext.getBean(OrderProcess.class);  

4.  System.out.println(bean.processOrder(<order>));  

 

[CXF] ServerClient实现方式二:Simple

博客分类: 

·        OpenSource

·        JAX-WS

 

【参考:http://cxf.apache.org/docs/jax-ws-configuration.html

【参考:http://cxf.apache.org/docs/writing-a-service-with-spring.html

【参考:http://cxf.apache.org/docs/simple-frontend-configuration.html

上节里,我们介绍了JAX-WS的创建Service和调用Service的方式。这节介绍另种实现方式:Simple。

 

除了支持通过读取jax-ws的annotation来生成webservice,CXF也支持直接从一个类对象生成webservice服务,这就是这里要介绍的simple frontend方式。

 

一、Service接口定义

Java代码  

1.  public interface OrderProcess {  

2.    

3.      String processOrder(Order order);  

4.        

5.  }  

 

没有任何jax-ws相关的annotation

二、Server的发布

Java代码  

1.  ServerFactoryBean bean = new ServerFactoryBean();  

2.  bean.setAddress("http://localhost:8181/cxf/simple");  

3.  bean.setServiceBean(new OrderProcessImpl());  

4.  bean.setServiceClass(OrderProcess.class);  

5.  bean.create();  

 或者是Spring方式:

Xml代码  

1.  <beans xmlns="http://www.springframework.org/schema/beans"  

2.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:simple="http://cxf.apache.org/simple"  

3.      xmlns:soap="http://cxf.apache.org/bindings/soap"  

4.      xsi:schemaLocation="  

5.  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  

6.  http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd  

7.  http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd">  

8.    

9.      <simple:server id="orderProcess"  

10.         serviceClass="com.liulutu.liugang.cxf.simple.OrderProcess" address="http://localhost:8181/cxf/simple">  

11.         <simple:serviceBean>  

12.             <bean class="com.liulutu.liugang.cxf.simple.OrderProcessImpl" />  

13.         </simple:serviceBean>  

14.     </simple:server>  

15. </beans>  

  三、Client端的实现

Java代码  

1.  ClientProxyFactoryBean client = new ClientProxyFactoryBean();  

2.    

3.  client.setAddress("http://localhost:8181/cxf/simple");  

4.  client.setServiceClass(OrderProcess.class);  

5.  OrderProcess orderProcess = (OrderProcess)client.create();  

6.  String s = orderProcess.processOrder(<order>);  

7.  System.out.println(s);  

 

或者是Spring的方式:

Xml代码  

1.  <beans xmlns="http://www.springframework.org/schema/beans"  

2.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:simple="http://cxf.apache.org/simple"  

3.      xmlns:soap="http://cxf.apache.org/bindings/soap"  

4.      xsi:schemaLocation="  

5.  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  

6.  http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd  

7.  http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd">  

8.    

9.      <simple:client id="orderClient"  

10.         serviceClass="com.liulutu.liugang.cxf.simple.OrderProcess" address="http://localhost:8181/cxf/simple">  

11.     </simple:client>  

12. </beans>  

 

然后在java代码里:

Java代码  

1.  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/com/liulutu/liugang/cxf/simple/client.xml");  

2.  OrderProcess bean = context.getBean("orderClient", OrderProcess.class);  

3.     String processOrder = bean.processOrder(<order>);  

4.     System.out.println(processOrder);  

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值