WebService CXF学习

sghakww 贡献于2012-01-12

作者 番茄花园  创建于2010-01-27 12:57:00   修改者番茄花园  修改于2010-01-27 13:51:00字数59688

文档摘要:CXF由来WebService介绍  WebService让一个程序可以透明地调用互联网程序,不用管具体的实现细节。只要WebService公开了服务接口,远程客户端就可以调用服务。WebService是基于http协议的组件服务,WebService是分散式应用程序的发展趋势。WebService的开源实现  WebService更多是一种标准,而不是一种具体的技术。不同的平台,不同的语言大都提供WebService的开发实现。在JAVA领域,WebService的框架很多,例如:AXIS,XFire,CXF等。AXIS,XFire相对比较成熟,资料相对较多。在这里我们只对CXF进行讲解,其他大家想学习到互联网找相关资料学习。
关键词:

WebService CXF学习(入门篇1):CXF由来 WebService介绍    WebService让一个程序可以透明地调用互联网程序,不用管具体的实现细节。只要WebService公开了服务接口,远程客户端就可以调用服务。WebService是基于http协议的组件服务,WebService是分散式应用程序的发展趋势。 WebService的开源实现    WebService更多是一种标准,而不是一种具体的技术。不同的平台,不同的语言大都提供WebService的开发实现。在JAVA领域,WebService的框架很多,例如:AXIS,XFire,CXF等。AXIS,XFire相对比较成熟,资料相对较多。在这里我们只对CXF进行讲解,其他大家想学习到互联网找相关资料学习。 CXF框架由来    ApacheCXF项目是由ObjectWeb Celtix和CodeHaus XFire合并成立。ObjectWeb Celtix是由IONA公司赞助,于2005年成立的开源Java ESB产品,XFire则是业界知名的SOAP堆栈。合并后的ApacheCXF融合该两个开源项目的功能精华,提供了实现SOA所需要的核心ESB功能框架,包括SOA服务创建,服务路由,及一系列企业级QoS功能。 ApacheCXF架框的目标    1.概述    <>高性能    <>可扩展    <>直观易用    2.支持标准     <> JAX-WS, JSR-181, SAAJ, JAX-RS     <> SOAP 1.1, 1.2, WS-I BasicProfile, WS-Security, WS-Addressing, WS-RM, WS-Policy     <> WSDL 1.1     <> MTOM    3.传输方式,绑定,数据绑定,传送数据格式     <> 绑定: SOAP, REST/HTTP     <> 数据绑定: JAXB 2.x, Aegis, XMLBeans, SDO     <> 传送数据格式: XML, JSON, FastInfoset     <> 传输方式: HTTP, Servlet, JMS    4.部署灵活     <> 轻量级: 可以将服务部署到 Tomcat或其支持Spring的容器中     <> JBI整合: 部署一个服务引擎到JBI容器,例如: ServiceMix, OpenESB or Petals     <> J2EE集成: 可以将服务部署到J2EE应用服务器上,例如:Geronimo, JOnAS, JBoss, WebLogic, 及WebSphere     <> Java 客户端/服务端可以独立性    5.支持多种编程语言     <> 完全支持 JAX-WS 2.x 客户端/服务端模式     <> JAX-WS 2.x synchronous, asynchronous and one-way API's     <> JAX-WS 2.x Dynamic Invocation Interface (DII) API     <> 支持 wrapped and non-wrapped 数据格式     <> XML messaging API     <> 支持JavaScript 和 ECMAScript 4 XML (E4X)     <> 支持CORBA     <> 支持JBI及ServiceMix    6.可编程环境     <> Java to WS DL     <> WSDL to Java     <> XSD to WSDL     <> WSDL to XML     <> WSDL to SOAP     <> WSDL to service WebService CXF学习(入门篇2):HelloWorld 理论联系实际,单单只讲理论那就成了纸上谈兵,用一个HelloWorld Demo可来说明事更加直观。那下面咱们就开始进行讲解:    首先到apache官方网下载apache-cxf-2.2.2,地址:http://cxf.apache.org/    新建一个Java Project,导入cxf常用.jar包 Java代码 1. commons-logging-1.1.1.jar    2. geronimo-activation_1.1_spec-1.0.2.jar (or Sun's Activation jar)    3. geronimo-annotation_1.0_spec-1.1.1.jar (JSR 250)    4. geronimo-javamail_1.4_spec-1.6.jar (or Sun's JavaMail jar)    5. geronimo-servlet_2.5_spec-1.2.jar (or Sun's Servlet jar)    6. geronimo-ws-metadata_2.0_spec-1.1.2.jar (JSR 181)    7. geronimo-jaxws_2.1_spec-1.0.jar (or Sun's jaxws-api-2.1.jar)    8. geronimo-stax-api_1.0_spec-1.0.1.jar (or other stax-api jar)    9. jaxb-api-2.1.jar    10. jaxb-impl-2.1.12.jar    11. jetty-6.1.21.jar    12. jetty-util-6.1.21.jar    13. neethi-2.0.4.jar    14. saaj-api-1.3.jar    15. saaj-impl-1.3.2.jar    16. wsdl4j-1.6.2.jar    17. wstx-asl-3.2.8.jar    18. XmlSchema-1.4.5.jar    19. xml-resolver-1.2.jar    20. cxf-2.2.2.jar   commons-logging-1.1.1.jar geronimo-activation_1.1_spec-1.0.2.jar (or Sun's Activation jar) geronimo-annotation_1.0_spec-1.1.1.jar (JSR 250) geronimo-javamail_1.4_spec-1.6.jar (or Sun's JavaMail jar) geronimo-servlet_2.5_spec-1.2.jar (or Sun's Servlet jar) geronimo-ws-metadata_2.0_spec-1.1.2.jar (JSR 181) geronimo-jaxws_2.1_spec-1.0.jar (or Sun's jaxws-api-2.1.jar) geronimo-stax-api_1.0_spec-1.0.1.jar (or other stax-api jar) jaxb-api-2.1.jar jaxb-impl-2.1.12.jar jetty-6.1.21.jar jetty-util-6.1.21.jar neethi-2.0.4.jar saaj-api-1.3.jar saaj-impl-1.3.2.jar wsdl4j-1.6.2.jar wstx-asl-3.2.8.jar XmlSchema-1.4.5.jar xml-resolver-1.2.jar cxf-2.2.2.jar    接下就是HelloWorld Demo开发了    第一步:新建一个webservice接口 Java代码 1. @WebService   2. public interface IHelloWorld {    3.     //@WebParam给参数命名,提高可代码可读性。此项可选    4. blic String sayHi(@WebParam(name="text") String text);    5. }   @WebService public interface IHelloWorld { //@WebParam给参数命名,提高可代码可读性。此项可选 public String sayHi(@WebParam(name="text") String text); }    通过注解@WebService申明为webservice接口    第二步,实现WebService接口 Java代码 1.   @WebService   2.   public class HelloWorldImpl implements IHelloWorld {    3.    4. public String sayHi(String name) {    5.     System.out.println("sayHello is called by " + name);    6.     return "Hello " + name;    7. }    8.    9.    }   @WebService public class HelloWorldImpl implements IHelloWorld { public String sayHi(String name) { System.out.println("sayHello is called by " + name); return "Hello " + name; } }    第三步,创建服务端 Java代码 1.   public class Server {    2.    3. private Server(){    4.     IHelloWorld helloWorld = new HelloWorldImpl();    5.     //创建WebService服务工厂    6.     JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();    7.     //注册WebService接口    8.     factory.setServiceClass(IHelloWorld.class);    9.     //发布接口    10.     factory.setAddress("http://localhost:9000/HelloWorld");    11.     factory.setServiceBean(helloWorld);    12.     //创建WebService    13.     factory.create();    14. };    15.    16. public static void main(String[] args) throws InterruptedException{    17.        //启动服务端    18.               new Server();    19.     System.out.println("Server ready...");    20.     //休眠一分钟,便于测试    21.                Thread.sleep(1000*60);    22.     System.out.println("Server exit...");    23.     System.exit(0);    24. }    25.    }   public class Server { private Server(){ IHelloWorld helloWorld = new HelloWorldImpl(); //创建WebService服务工厂 JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); //注册WebService接口 factory.setServiceClass(IHelloWorld.class); //发布接口 factory.setAddress("http://localhost:9000/HelloWorld"); factory.setServiceBean(helloWorld); //创建WebService factory.create(); }; public static void main(String[] args) throws InterruptedException{ //启动服务端 new Server(); System.out.println("Server ready..."); //休眠一分钟,便于测试 Thread.sleep(1000*60); System.out.println("Server exit..."); System.exit(0); } }     第四步,创建客户端    Java代码 1.    public class Client {    2.    3. private Client(){};    4.    5. public static void main(String[] args){    6.     //创建WebService客户端代理工厂    7.     JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();    8.     //注册WebService接口    9.     factory.setServiceClass(HelloWorld.class);    10.     //设置WebService地址    11.     factory.setAddress("http://localhost:9000/HelloWorld");         12.     IHelloWorld iHelloWorld = (IHelloWorld)factory.create();    13.     System.out.println("invoke webservice...");    14.     System.out.println("message context is:"+iHelloWorld.sayHi("      15.                  Josen"));    16.     System.exit(0);    17. }    18.    }    19.      public class Client { private Client(){}; public static void main(String[] args){ //创建WebService客户端代理工厂 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); //注册WebService接口 factory.setServiceClass(HelloWorld.class); //设置WebService地址 factory.setAddress("http://localhost:9000/HelloWorld"); IHelloWorld iHelloWorld = (IHelloWorld)factory.create(); System.out.println("invoke webservice..."); System.out.println("message context is:"+iHelloWorld.sayHi(" Josen")); System.exit(0); } }     最后是万事俱备,只欠测试了     首先,运行服务端程序     其次,打开浏览器,在地址栏中输入http://localhost:9000/HelloWorld?wsdl(因为cxf自带了一个jetty服务器),查看接口是否发布成功,如里浏览器页面显示下面内容,证明接口发布成功 Java代码 1.        2.    3.    4.    5.    6.    7.    8.    9.    10.    11.    12.    13.    14.    15.    16.    17.    18.    19.    20.         21.    22.    23.    24.         25.    26.    27.    28.    29.         30.    31.         32.    33.    34.    35.    36.    37.    38.    39.    40.    41.    42.    43.    44.    45.    46.    47.    48.    49.    50.    51.        最后,运行客户端程序,看看效果如果。     这一节就讲到此为止,下节对WSDL定义进行讲解,便于对上面这个Demo进行很好的消化,同时对后面章节启个辅塾作用。 WebService CXF学习(入门篇3):WSDL描述 由于网上有很多相关这方面的资料,在这里我就转载http://www.ibm.com/developerworks/cn/webservices/ws-wsdl/index.html一篇,不再重新讲述了。     本文初步介绍了Web Service 'stack'中对于Web服务即时装配,自动集成起着关键作用的WSDL规范,首先介绍了WSDL的作用和意义,其次对WSDL文档的结构作出概要地介绍,对每个元素的作用作了探讨,分析了其开放和复用的体系设计的思想,最后通过一个实例详细说明了WSDL的工作模式。     本文所引用的资源主要包括两类,一类是Web服务的技术资源网站,包含了大量Web服务的技术信息,另一类是Web服务“stack"系列技术规范,他们是一个整体的技术体系,包括UDDI、SOAP、WSDL、XML等。本文的最后给出了这些资源的链接,有兴趣的读者可以通过这些资源链接找到所需的内容。 Web Service "Stack"     在我的先前的文章中,我已经介绍过Web服务的整个技术体系Web Service "stack",如下图: Figure 1. Web Service "stack" 其中,绿色部分是先前已经定义好的并且广泛使用的传输层和网络层的标准:IP、HTTP、SMTP等。而蓝色部分是目前开发的Web服务的相关标准协议,包括服务调用协议SOAP、服务描述协议WSDL和服务发现/集成协议UDDI,以及服务工作流描述语言WSFL。而橙色部分描述的是更高层的待开发的关于路由、可靠性以及事务等方面的协议。黄色部分是各个协议层的公用机制,这些机制一般由外部的正交机制来完成。 其中,一个可以使用的Web服务应当按照需要选用若干层次的功能,而无需所有的特性。但是无论如何为了实现一个一般意义上的Web服务,具备Web服务的基础特性:跨平台调用和接口可机器识别,那么必需使用WSDL和SOAP。SOAP是用来最终完成Web服务调用的,而WSDL则是用于描述如何使用 SOAP来调用Web服务的。     WSDL 是一种XML Application,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务访问点对包含面向文档信息或面向过程调用的服务进行访问(类似远程过程调用)。WSDL首先对访问的操作和访问时使用的请求/响应消息进行抽象描述,然后将其绑定到具体的传输协议和消息格式上以最终定义具体部署的服务访问点。相关的具体部署的服务访问点通过组合就成为抽象的Web服务。     在具体使用中,我们可以对 WSDL 进行扩展(类似SOAP的可扩展性),这样无论通信时使用何种消息格式或网络协议,都可以对服务访问点及其使用的消息格式进行描述。在WSDL的框架中,可以使用任意的消息格式和网络协议,如同SOAP中可以使用任意的网络协议一样。在WSDL规范中,定义了如何使用SOAP消息格式、HTTP GET/POST消息格式以及MIME格式来完成Web服务交互的规范。 WSDL概述     由于通信协议和消息格式在 Web 技术圈子里已经达到了标准化,我们知道在通常的开发过程中,对于对象的Interface一定具备相应的SDK描述文档,Web服务也是一种对象,只不过它是被部署在Web上而已。很自然的,我们也完全需要有对Web服务这个对象的界面的SDK描述文档。然而这两者又不尽相同,一来目前在Web上的应用已经完全接受了XML这个基本的标准,基本上所有新出台的技术都是基于XML标准的,二来Web服务的目标是即时装配,松散耦合以及自动集成的,这意味着 SDK描述文档应当是具备被机器识别的能力的。     也就是说,对于使用标准化的消息格式/通信协议的Web服务,它需要以某种结构化的方式(即XML)对Web服务的调用/通信加以描述,而且实现这一点也显得非常重要,这是Web服务即时装配的基本保证。WSDL正是这样一种描述语言,WSDL 定义了一套基于 XML的语法,将Web服务描述为能够进行消息交换的服务访问点的集合,从而满足了这种需求。WSDL 服务定义为分布式系统提供了可机器识别的SDK文档,并且可用于描述自动执行应用程序通信中所涉及的细节。     WSDL 文档将Web服务定义为服务访问点或端口的集合。在 WSDL 中,由于服务访问点和消息的抽象定义已从具体的服务部署或数据格式绑定中分离出来,因此可以对抽象定义进行再次使用:消息,指对交换数据的抽象描述;而端口类型,指操作的抽象集合。用于特定端口类型的具体协议和数据格式规范构成了可以再次使用的绑定。将Web访问地址与可再次使用的绑定相关联,可以定义一个端口,而端口的集合则定义为服务。因此,WSDL 文档在Web服务的定义中使用下列元素:     * Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。     * Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。     * Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。     * PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。     * Binding - 特定端口类型的具体协议和数据格式规范的绑定。     * Port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。     * Service - 相关服务访问点的集合。 大家可以参考下图,来理解一下WSDL文档的结构组织: Figure 2. WSDL元素的对象结构示意图     其中,Types是一个数据类型定义的容器,包含了所有在消息定义中需要的XML元素的类型定义,我将在今后的文章中结合XML Schema来详细说明如何进行类型定义。     Message具体定义了在通信中使用的消息的数据结构,Message元素包含了一组Part元素,每个Part元素都是最终消息的一个组成部分,每个 Part都会引用一个DataType来表示它的结构。Part元素不支持嵌套(可以使用DataType来完成这方面的需要),都是并列出现。     PortType具体定义了一种服务访问入口的类型,何谓访问入口的类型呢?就是传入/传出消息的模式及其格式。一个PortType可以包含若干个 Operation,而一个Operation则是指访问入口支持的一种类型的调用。在WSDL里面支持四种访问入口调用的模式:    1. 单请求;    2. 单响应;    3. 请求/响应;    4. 响应/请求。     在这里请求指的是从客户端到Web服务端,而响应指的是从Web服务端到客户端。PortType的定义中会引用消息定义部分的一个到两个消息,作为请求或响应消息的格式。比如,一个股票查询的访问入口可能就会支持两种请求消息,一种请求消息中指明股票代码,而另一种请求消息中则会指明股票的名称,响应消息可能都是股票的价格等等。     以上三种结构描述了调用Web服务的抽象定义,这三部分与具体Web服务部署细节无关,是可复用的描述(每个层次都可以复用)。如果与一般的对象语言做比较的话,这部分可以堪称是IDL描述的对象,描述了对象的接口标准,但是到底对象是用哪种语言实现,遵从哪种平台的细节规范,被部署在哪台机器上则是后面的元素所描述的。     Service描述的是一个具体的被部署的Web服务所提供的所有访问入口的部署细节,一个Service往往会包含多个服务访问入口,而每个访问入口都会使用一个Port元素来描述。     Port描述的是一个服务访问入口的部署细节,包括通过哪个Web地址(URL)来访问,应当使用怎样的消息调用模式来访问等。其中消息调用模式则是使用Binding结构来表示。     Binding结构定义了某个PortType与某一种具体的网络传输协议或消息传输协议相绑定,从这一层次开始,描述的内容就与具体服务的部署相关了。比如可以将PortType与SOAP/HTTP绑定,也可以将PortType与MIME/SMTP相绑定等。     在介绍了WSDL的主要元素之后,大家会发现,WSDL的设计理念完全继承了以XML为基础的当代Web技术标准的一贯设计理念:开放。WSDL允许通过扩展使用其他的类型定义语言(不光是XML Schema),允许使用多种网络传输协议和消息格式(不光是在规范中定义的这些:SOAP/HTTP,HTTP-GET/POST以及MIME等)。同时WSDL也应用了当代软件工程中的复用理念,分离了抽象定义层和具体部署层,使得抽象定义层的复用性大大增加。比如我们可以先使用抽象定义层为一类 Web服务进行抽象定义(比如UDDI Registry,抽象定义肯定是完全一致的遵循了UDDI规范),而不同的运营公司可以采用不同的具体部署层的描述结合抽象定义完成其自身的Web服务的描述。 WSDL文档示例     下例是一个提供股票报价的简单Web服务的 WSDL 定义。该服务支持名为 GetLastTradePrice 的单一操作,这个操作是通过在 HTTP 上运行 SOAP 1.1 协议来实现的。该请求接受一个类型为字符串的 tickerSymbol,并返回类型为浮点数的价格。 Java代码 1.    2.    8.                  9.      10.       11.         13.           14.             15.               16.                 17.               18.             19.           20.           21.             22.               23.                 24.               25.             26.           27.         28.          上面这部分是数据类型的定义,其中为定义了两个元素的结构:     * TradePriceRequest(交易价格请求): 将该元素定义为包含一个字符串元素(tickerSymbol)的复合类型元素。     * TradePriceResult(交易价格): 将该元素定义为一个包含一个浮点数元素(price)的复合类型元素。 Java代码 1.    2.         3.       4.      5.       6.         7.          这部分是消息格式的抽象定义,其中定义了两个消息格式:     * GetlastTradePriceInput(获取最后交易价格的请求消息格式): 由一个消息片断组成,该消息片断的名字是body,包含的具体元素类型是TradePriceRequest。(前面已经定义过了)     * GetLastTradePriceOutput(获取最后交易价格的响应消息格式) : 由一个消息片断组成,该消息片断的名字是body,包含的具体元素类型是TradePriceResult。(前面已经定义过了) Java代码 1.    2.        3.          4.          5.        6.         这部分定义了服务访问点的调用模式的类型,表明StockQuoteService的某个入口类型是请求/响应模式,请求消息是GetlastTradePriceInput,而响应消息是GetLastTradePriceOutput。 Java代码 1.    2.         3.           4.             5.               6.                 8.               9.               10.                 12.               13.             14.           15.         16.          这部分将服务访问点的抽象定义与SOAP HTTP绑定,描述如何通过SOAP/HTTP来访问按照前面描述的访问入口点类型部署的访问入口。其中规定了在具体SOAP调用时,应当使用的 soapAction是"http://example.com/GetLastTradePrice",而请求/响应消息的编码风格都应当采用SOAP 规范默认定义的编码风格" http://schemas.xmlsoap.org/soap/encoding/"。 Java代码 1.    2.     股票查询服务     3.         4.         5.         6.       7.      8.    股票查询服务     这部分是具体的Web服务的定义,在这个名为StockQuoteService的Web服务中,提供了一个服务访问入口,访问地址是"http://example.com/stockquote",使用的消息模式是由前面的binding所定义的。     按照这个WSDL文档的描述,在具体Web服务的使用中,具体发生的SOAP交互可能如下面所示: SOAP消息请求: Java代码 1. POST /StockQuote HTTP/1.1   2. Host: example.com    3. Content-Type: text/xml; charset="utf-8"   4. Content-Length: nnnn    5. SOAPAction: "http://example.com/GetLastTradePrice"   6.    7.    9.       10.         11.       MSFT    12.         13.       14.    POST /StockQuote HTTP/1.1 Host: example.com Content-Type: text/xml; charset="utf-8" Content-Length: nnnn SOAPAction: "http://example.com/GetLastTradePrice" MSFT SOAP消息响应: Java代码 1. HTTP/1.1 200 OK    2. Content-Type: text/xml; charset="utf-8"   3. Content-Length: nnnn    4.    5.    7.       8.         9.       74.5    10.         11.       12.    HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" Content-Length: nnnn 74.5 小结     在本文中,我简单介绍了WSDL规范的用途 下面提供几个相关资料的网址 理解 UDDI 注册中心的 WSDL http://www.ibm.com/developerworks/cn/webservices/ws-uwsdl/part1/index.html Web 服务的(革)创新 http://www.ibm.com/developerworks/cn/webservices/ws-peer4/index.html WebService CXF学习(进阶篇1):SOAP讲解 SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换。或者更简单地说:SOAP 是用于访问网络服务的协议。     您应当具备的基础知识     在继续学习之前,您需要对下面的知识有基本的了解:         * XML         * XML 命名空间     Why SOAP?     对于应用程序开发来说,使程序之间进行因特网通信是很重要的。     目前的应用程序通过使用远程过程调用(RPC)在诸如 DCOM 与 CORBA 等对象之间进行通信,但是 HTTP 不是为此设计的。RPC 会产生兼容性以及安全问题;防火墙和代理服务器通常会阻止此类流量。     通过 HTTP 在应用程序间通信是更好的方法,因为 HTTP 得到了所有的因特网浏览器及服务器的支持。SOAP 就是被创造出来完成这个任务的。     SOAP 提供了一种标准的方法,使得运行在不同的操作系统并使用不同的技术和编程语言的应用程序可以互相进行通信。     Microsoft 和 SOAP     SOAP 是微软 .net 架构的关键元素,用于未来的因特网应用程序开发。     SOAP 1.1 被提交到 W3C     在 2000 年 5 月,UserLand、Ariba、Commerce One、Compaq、Developmentor、HP、IBM、IONA、Lotus、Microsoft 以及 SAP 向 W3C 提交了 SOAP 因特网协议,这些公司期望此协议能够通过使用因特网标准(HTTP 以及 XML)把图形用户界面桌面应用程序连接到强大的因特网服务器,以此来彻底变革应用程序的开发。    W3C 正在发展 SOAP 1.2    首个关于 SOAP 的公共工作草案由 W3C 在 2001 年 12 月发布。如需阅读更多有关在 W3C 的 SOAP 活动的内容,请访问我们的《W3C 教程》。    SOAP 构建模块     一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:     * 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息     * 可选的 Header 元素,包含头部信息     * 必需的 Body 元素,包含所有的调用和响应信息     * 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息     所有以上的元素均被声明于针对 SOAP 封装的默认命名空间中:     http://www.w3.org/2001/12/soap-envelope     以及针对 SOAP 编码和数据类型的默认命名空间:     http://www.w3.org/2001/12/soap-encoding 语法规则     这里是一些重要的语法规则:     * SOAP 消息必须用 XML 来编码     * SOAP 消息必须使用 SOAP Envelope 命名空间     * SOAP 消息必须使用 SOAP Encoding 命名空间     * SOAP 消息不能包含 DTD 引用     * SOAP 消息不能包含 XML 处理指令 SOAP 消息的基本结构 Java代码 1.    2.    5.    6.    7.   ...    8.   ...    9.    10.    11.    12.   ...    13.   ...    14.       15.     ...    16.     ...    17.       18.    19.    20.    ... ... ... ... ... ... SOAP Envelope 元素     必需的 SOAP 的 Envelope 元素是 SOAP 消息的根元素。它可把 XML 文档定义为 SOAP 消息。     请注意 xmlns:soap 命名空间的使用。它的值应当始终是: Java代码 1. http://www.w3.org/2001/12/soap-envelope   http://www.w3.org/2001/12/soap-envelope     并且它可把封装定义为 SOAP 封装: Java代码 1.    2.    5.   ...    6.   Message information goes here    7.   ...    8.    ... Message information goes here ... xmlns:soap 命名空间     SOAP 消息必须拥有与命名空间 "http://www.w3.org/2001/12/soap-envelope" 相关联的一个 Envelope 元素。     如果使用了不同的命名空间,应用程序会发生错误,并抛弃此消息。 encodingStyle 属性    SOAP 的 encodingStyle 属性用于定义在文档中使用的数据类型。此属性可出现在任何 SOAP 元素中,并会被应用到元素的内容及元素的所有子元素上。SOAP 消息没有默认的编码方式。 语法 Java代码 1. soap:encodingStyle="URI"   soap:encodingStyle="URI" 实例 Java代码 1.    2.    5. ...    6. Message information goes here    7. ...    8.    ... Message information goes here ... SOAP Header 元素     可选的 SOAP Header 元素可包含有关 SOAP 消息的应用程序专用信息(比如认证、支付等)。如果 Header 元素被提供,则它必须是 Envelope 元素的第一个子元素。      注释:所有 Header 元素的直接子元素必须是合格的命名空间。 Java代码 1.    2.    5.    6.    7. 234    10.    11.    12. ...    13. ...    14.    15.    234 ... ...     上面的例子包含了一个带有一个 "Trans" 元素的头部,它的值是 234,此元素的 "mustUnderstand" 属性的值是 "1"。     SOAP 在默认的命名空间中 ("http://www.w3.org/2001/12/soap-envelope") 定义了三个属性。这三个属性是:actor、 mustUnderstand 以及 encodingStyle。这些被定义在 SOAP 头部的属性可定义容器如何对 SOAP 消息进行处理。 actor 属性     通过沿着消息路径经过不同的端点,SOAP 消息可从某个发送者传播到某个接收者。并非 SOAP 消息的所有部分均打算传送到 SOAP 消息的最终端点,不过,另一个方面,也许打算传送给消息路径上的一个或多个端点。     SOAP 的 actor 属性可被用于将 Header 元素寻址到一个特定的端点。 语法 Java代码 1. soap:actor="URI"    soap:actor="URI" 实例 Java代码 1.    2.    5.    6.    7.    10. 234   11.    12.    13.    14. ...    15. ...    16.    17.    234 ... ... mustUnderstand 属性     SOAP 的 mustUnderstand 属性可用于标识标题项对于要对其进行处理的接收者来说是强制的还是可选的。     假如您向 Header 元素的某个子元素添加了 "mustUnderstand="1",则它可指示处理此头部的接收者必须认可此元素。假如此接收者无法认可此元素,则在处理此头部时必须失效。 语法 Java代码 1. soap:mustUnderstand="0|1"   soap:mustUnderstand="0|1" 实例 Java代码 1.    2.    5.    6.    7.    10. 234   11.    12.    13.    14. ...    15. ...    16.    17.    234 ... ... encodingStyle 属性     SOAP 的 encodingStyle 属性在上一节中已解释过了。 SOAP Body 元素     必需的 SOAP Body 元素可包含打算传送到消息最终端点的实际 SOAP 消息。     SOAP Body 元素的直接子元素可以是合格的命名空间。SOAP 在默认的命名空间中("http://www.w3.org/2001/12/soap-envelope")定义了 Body 元素内部的一个元素。即 SOAP 的 Fault 元素,用于指示错误消息。 Java代码 1.    2.    5.    6.    7.        8.       Apples    9.        10.    11.    12.    Apples     上面的例子请求苹果的价格。请注意,上面的 m:GetPrice 和 Item 元素是应用程序专用的元素。它们并不是 SOAP 标准的一部分。     而一个 SOAP 响应应该类似这样: Java代码 1.    2.    5.    6.    7.        8.       1.90    9.        10.    11.    12.    1.90 SOAP Fault 元素     来自 SOAP 消息的错误消息被携带于 Fault 元素内部。     如果已提供了 Fault 元素,则它必须是 Body 元素的子元素。在一条 SOAP 消息中,Fault 元素只能出现一次。     SOAP 的 Fault 元素用于下列子元素:     子元素         描述           供识别故障的代码    可供人阅读的有关故障的说明    有关是谁引发故障的信息    存留涉及 Body 元素的应用程序专用错误信息 SOAP Fault Codes     在下面定义的 faultcode 值必须用于描述故障时的 faultcode 元素中: 错误 描述 VersionMismatch SOAP Envelope 元素的无效命名空间被发现 MustUnderstand Header 元素的一个直接子元素(带有设置为 "1" 的 mustUnderstand 属性)无法被理解。 Client 消息被不正确地构成,或包含了不正确的信息。 Server 服务器有问题,因此无法处理进行下去。 HTTP 协议     HTTP 在 TCP/IP 之上进行通信。HTTP 客户机使用 TCP 连接到 HTTP 服务器。在建立连接之后,客户机可向服务器发送 HTTP 请求消息: Java代码 1. POST /item HTTP/1.1   2. Host: 189.123.345.239   3. Content-Type: text/plain    4. Content-Length: 200   POST /item HTTP/1.1 Host: 189.123.345.239 Content-Type: text/plain Content-Length: 200     随后服务器会处理此请求,然后向客户机发送一个 HTTP 响应。此响应包含了可指示请求状态的状态代码: Java代码 1. 200 OK    2. Content-Type: text/plain    3. Content-Length: 200   200 OK Content-Type: text/plain Content-Length: 200    在上面的例子中,服务器返回了一个 200 的状态代码。这是 HTTP 的标准成功代码。    假如服务器无法对请求进行解码,它可能会返回类似这样的信息: Java代码 1. 400 Bad Request    2. Content-Length: 0   400 Bad Request Content-Length: 0 SOAP HTTP Binding    SOAP 方法指的是遵守 SOAP 编码规则的 HTTP 请求/响应。    HTTP + XML = SOAP    SOAP 请求可能是 HTTP POST 或 HTTP GET 请求。    HTTP POST 请求规定至少两个 HTTP 头:Content-Type 和 Content-Length。 Content-Type    SOAP 的请求和响应的 Content-Type 头可定义消息的 MIME 类型,以及用于请求或响应的 XML 主体的字符编码(可选) 语法 Java代码 1. Content-Type: MIMEType; charset=character-encoding    Content-Type: MIMEType; charset=character-encoding 例子 Java代码 1. POST /item HTTP/1.1   2. Content-Type: application/soap+xml; charset=utf-8   POST /item HTTP/1.1 Content-Type: application/soap+xml; charset=utf-8 Content-Length    SOAP 的请求和响应的 Content-Length 头规定请求或响应主体的字节数。 语法 Java代码 1. Content-Length: bytes   Content-Length: bytes 例子 Java代码 1. POST /item HTTP/1.1   2. Content-Type: application/soap+xml; charset=utf-8   3. Content-Length: 250   POST /item HTTP/1.1 Content-Type: application/soap+xml; charset=utf-8 Content-Length: 250 一个 SOAP 实例     在下面的例子中,一个 GetStockPrice 请求被发送到了服务器。此请求有一个 StockName 参数,而在响应中则会返回一个 Price 参数。此功能的命名空间被定义在此地址中: "http://www.example.org/stock" SOAP 请求: Java代码 1. POST /InStock HTTP/1.1   2. Host: www.example.org    3. Content-Type: application/soap+xml; charset=utf-8   4. Content-Length: nnn    5.    6.    7.    10.    11.       12.         13.       IBM    14.         15.       16.       17.    POST /InStock HTTP/1.1 Host: www.example.org Content-Type: application/soap+xml; charset=utf-8 Content-Length: nnn IBM SOAP 响应: Java代码 1. HTTP/1.1 200 OK    2. Content-Type: application/soap+xml; charset=utf-8   3. Content-Length: nnn    4.    5.    6.    9.    10.       11.         12.       34.5    13.         14.       15.       16.    WebService CXF学习(进阶篇2):JAX-WS讲解 JAX-WS规范是一组XML web services的JAVA API。JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。   在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP。在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。JAX-WS的运行时实现会将这些API的调用转换成为对于SOAP消息。   在服务器端,用户只需要通过Java语言定义远程调用所需要实现的接口SEI (service endpoint interface),并提供相关的实现,通过调用JAX-WS的服务发布接口就可以将其发布为WebService接口。   在客户端,用户可以通过JAX-WS的API创建一个代理(用本地对象来替代远程的服务)来实现对于远程服务器端的调用。   通过web service所提供的互操作环境,我们可以用JAX-WS轻松实现JAVA平台与其他编程环境(.net等)的互操作。     JAX-WS工作原理如下图所示:   JAX-WS与JAX-RPC之间的关系   Sun最开始的web services的实现是JAX-RPC 1.1 (JSR 101)。这个实现是基于Java的RPC,并不完全支持schema规范,同时没有对Binding和Parsing定义标准的实现。   JAX-WS2.0 (JSR 224)是Sun新的web services协议栈,是一个完全基于标准的实现。在binding层,使用的是the Java Architecture for XML Binding (JAXB, JSR 222),在parsing层,使用的是the Streaming API for XML (StAX, JSR 173),同时它还完全支持schema规范。 WebService CXF学习(进阶篇3):对象传递 前面几节都是讲一些理论知识,现在又用一个例子来说明一下,这一节我们就CXF框架对象传递进行讲解。     第一步:创建传输对象Customer Java代码 1.    @XmlRootElement(name="Customer")    2.    @XmlAccessorType(XmlAccessType.FIELD)    3.    @XmlType(propOrder = {"name","age"})    4.    public class Customer {    5.    6. private int age;    7. private String name;    8.    9. public int getAge() {    10.     return age;    11. }    12.    13. public void setAge(int age) {    14.     this.age = age;    15. }    16.    17. public String getName() {    18.     return name;    19. }    20.    21. public void setName(String name) {    22.     this.name = name;    23. }    24.    25.    }   @XmlRootElement(name="Customer") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(propOrder = {"name","age"}) public class Customer { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }     @XmlRootElement-指定XML根元素名称(可选)     @XmlAccessorType-控制属性或方法序列化     四种方案:     FIELD-对每个非静态,非瞬变属性JAXB工具自动绑定成XML,除非注明XmlTransient     NONE-不做任何处理     PROPERTY-对具有set/get方法的属性进行绑定,除非注明XmlTransient     PUBLIC_MEMBER -对有set/get方法的属性或具有共公访问权限的属性进行绑定,除非注     明XmlTransient     @XmlType-映射一个类或一个枚举类型成一个XML Schema类型    第二步:创建WebService接口    Java代码 1.   @WebService   2.   public interface HelloService {    3.    4. public void save(Customer c1,Customer c2);    5.    6. public void test(String args);    7.    8. public Customer get(int id);    9.  }    10.    11.      @WebService public interface HelloService { public void save(Customer c1,Customer c2); public void test(String args); public Customer get(int id); }    每三步:创建WebService接口实现类    Java代码 1.   @WebService   2.   public class HelloServiceImpl implements HelloService {    3.    4. public void save(Customer c1, Customer c2) {    5.    6.     System.out.println(c1.getAge()+"---"+c2.getAge());    7.     System.out.println(c1.getName()+"---"+c2.getName());    8. }    9.    10. public void test(String args) {    11.     System.out.println(args);    12.         13. }    14.    15. public Customer get(int id) {    16.     Customer cus = new Customer();    17.     cus.setAge(100);    18.     cus.setName("Josen");    19.     return cus;    20. }    21.    22.    23.    24.    }    25.      @WebService public class HelloServiceImpl implements HelloService { public void save(Customer c1, Customer c2) { System.out.println(c1.getAge()+"---"+c2.getAge()); System.out.println(c1.getName()+"---"+c2.getName()); } public void test(String args) { System.out.println(args); } public Customer get(int id) { Customer cus = new Customer(); cus.setAge(100); cus.setName("Josen"); return cus; } }    第四步:创建服务端    Java代码 1.  public class SoapServer {    2.    3. ublic static void main(String[] args){    4. //两种方法,任选一种发布WebService接口    5.               //Endpoint.publish("http://localhost:8080/helloService", new     6.                HelloServiceImpl());    7. JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();    8. factory.setAddress("http://localhost:8080/helloService");    9. factory.setServiceClass(HelloServiceImpl.class);    10.               factory.getInInterceptors().add(new LoggingInInterceptor());          11. factory.getOutInterceptors().add(new LoggingOutInterceptor());    12. factory.create();    13.    14.   }    15.     public class SoapServer { public static void main(String[] args){ //两种方法,任选一种发布WebService接口 //Endpoint.publish("http://localhost:8080/helloService", new HelloServiceImpl()); JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); factory.setAddress("http://localhost:8080/helloService"); factory.setServiceClass(HelloServiceImpl.class); factory.getInInterceptors().add(new LoggingInInterceptor()); factory.getOutInterceptors().add(new LoggingOutInterceptor()); factory.create(); } }   第五步:创建客户端   Java代码 1.  public class SoapClient {    2.    3. public static void main(String[] args){    4.     JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();    5.     factory.setAddress("http://localhost:8080/helloService");    6.     factory.setServiceClass(HelloService.class);    7.                factory.setServiceClass(HelloServiceImpl.class);    8.                factory.getInInterceptors().add(new LoggingInInterceptor());    9.     HelloService service = (HelloService)factory.create();    10.         11.     Customer c1 = new Customer();    12.     c1.setAge(1);    13.     c1.setName("aaa");    14.         15.     Customer c2 = new Customer();    16.     c2.setAge(2);    17.     c2.setName("bbb");    18.         19.     service.save(c1, c2);    20.     service.test("aaaaaaaaaaaaa");    21. }    22.  }    23.     public class SoapClient { public static void main(String[] args){ JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setAddress("http://localhost:8080/helloService"); factory.setServiceClass(HelloService.class); factory.setServiceClass(HelloServiceImpl.class); factory.getInInterceptors().add(new LoggingInInterceptor()); HelloService service = (HelloService)factory.create(); Customer c1 = new Customer(); c1.setAge(1); c1.setName("aaa"); Customer c2 = new Customer(); c2.setAge(2); c2.setName("bbb"); service.save(c1, c2); service.test("aaaaaaaaaaaaa"); } }   最后,测试程序   运行服务端程序,在浏览器地址栏输入http://localhost:8080/helloService?wsdl查看接口是否发布成功。成功则运行一下客户端程序,看看对象传输是否成功。    现在我们来分析一下控制打印的日志信息。 引用 信息: Inbound Message ---------------------------- ID: 1 Address: /HelloWorld Encoding: UTF-8 Content-Type: text/xml; charset=UTF-8 Headers: {content-type=[text/xml; charset=UTF-8], connection=[keep-alive], Host=[localhost:9000], Content-Length=[184], SOAPAction=[""], User-Agent=[Apache CXF 2.2.2], Content-Type=[text/xml; charset=UTF-8], Accept=[*/*], Pragma=[no-cache], Cache-Control=[no-cache]} Payload: Josen -------------------------------------- 2010-1-9 20:41:56 org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose 信息: Outbound Message --------------------------- ID: 1 Encoding: UTF-8 Content-Type: text/xml Headers: {} Payload: hi Josen -------------------------------------- 2010-01-09 20:41:56.578::INFO:  seeing JVM BUG(s) - cancelling interestOps==0      当客户端向服器发送请求时,服务端LoggingInInterceptor拉截客户端发送过来的SOAP消息,如下: 引用 Josen      客户端将请求信息封闭在中,当然也可以将其放到,只要在@WebParam中的header设置成true,默认为false;      服务器接到请求之后,响应客户端。同样以SOAP形式将信息封装好发回客户端,SOAP信息如下: 引用 hi Josen WebService CXF学习(进阶篇4):JAXB剖析 前面几节我们讲解对象传递,但是通常情况下我们不直接传对象,因为直接传递对象安全性差,而且暴露了实体对象。所以我们选择传递XML文件,当然也可以传递JSON对象。这节我只针对传递XML,那么JAVA绑定成XML,服务端将XML解析成Java对象有什么工具可用吗,其实这样的工具多的是。这里我选择一个比较简单的JAXB工具来讲解一下。     JAXB(Java Architecture for XML Binding)提供了一个快速而方便的方式绑定XML Schemas和java,使java程序员能够很方便的在java应用程序中处理XML数据。JAXB提供了将XML文档解组为java内容树的方法,以及将java内容树重新编组回XML文档的方法。JAXB同样也提供了一种从java对象生成XML Schema的方式。     这里有几个重要的定义:     编组(Marshalling)是把内存中的数据转化到存储媒介上的过程。因此在 Java 和 XML 环境中,编组就是把一些 Java 对象转化成一个(或多个) XML 文档。在数据库环境中,则是把 Java 表示的数据存入数据库。显然,编组的秘密在于把 Java 实例中的面向对象结构转化成适用于 XML 的 扁平结构,或者 RDBMS 中的关系结构(使用 Java 技术转换到 OODBMS 实际上很简单)。工作原理如下图所示:     解组(Unmarshalling) 是把数据从存储媒介转换到内存中的过程--正好与编组相反。因此需要把 XML 文档解组到 Java VM 中。这里的复杂性不是在扁平数据中,因为这不是必需的,而在于从正确的数据到正确的 Java 代码变量的映射。如果映射是错误的,就不可能正确地访问数据。当然,如果再尝试重新编组还会造成更大的问题,并且问题传播得很快。工作原理如下图所示:     往返(Round-tripping)可能是最重要也最容易误解的数据绑定术语。往返用于描述从存储媒介到内存然后回到存储媒介的完整循 环。在 XML 和 Java 技术环境中,这就意味着从 XML 文档到 Java 实例变量,然后再回到 XML 文档。正确的往返要求,如果中间没有修改数据,XML 输入和 XML 输出应该是等同的。     下载地址:http://java.sun.com/developer/technicalArticles/WebServices/jaxb/        我们还以例子来说明它的工作原理,直观点。     第一步,创建一个Customer对象     Java代码 1. @XmlRootElement(name="customer")    2. @XmlAccessorType(XmlAccessType.FIELD)    3. @XmlType(name = "")    4. public class Customer {    5.    6.     @XmlAttribute(required = true)    7.     protected String name;    8.     @XmlAttribute(required = true)    9.     protected int age;    10.    11.     /**   12.      * Gets the value of the name property.   13.      *    14.      * @return   15.      *     possible object is   16.      *     {@link String }   17.      *        18.      */   19.     public String getName() {    20.         return name;    21.     }    22.    23.     /**   24.      * Sets the value of the name property.   25.      *    26.      * @param value   27.      *     allowed object is   28.      *     {@link String }   29.      *        30.      */   31.     public void setName(String value) {    32.         this.name = value;    33.     }    34.    35.     /**   36.      * Gets the value of the age property.   37.      *    38.      */   39.     public int getAge() {    40.         return age;    41.     }    42.    43.     /**   44.      * Sets the value of the age property.   45.      *    46.      */   47.     public void setAge(int value) {    48.         this.age = value;    49.     }    50.    51. }    52.    53.        @XmlRootElement(name="customer") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "") public class Customer { @XmlAttribute(required = true) protected String name; @XmlAttribute(required = true) protected int age; /** * Gets the value of the name property. * * @return * possible object is * {@link String } * */ public String getName() { return name; } /** * Sets the value of the name property. * * @param value * allowed object is * {@link String } * */ public void setName(String value) { this.name = value; } /** * Gets the value of the age property. * */ public int getAge() { return age; } /** * Sets the value of the age property. * */ public void setAge(int value) { this.age = value; } }     第二步,创建一个测试类 Java代码 1. public class SoapClient {    2.    3.     private final static String MODEL = "com.itdcl.model";    4.     public static void main(String[] args) throws ParserConfigurationException, JAXBException, TransformerException{    5.    6.             7.         ObjectFactory factory = new ObjectFactory();    8.         Customer customer = factory.createCustomer();    9.         customer.setAge(20);    10.         customer.setName("Josen");    11.    12.         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    13.         dbf.setNamespaceAware(true);    14.         DocumentBuilder db = dbf.newDocumentBuilder();    15.         Document doc = db.newDocument();    16.    17.         JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);    18.         //Java对象转换成XML    19.                 Marshaller marshaller = jaxbContext.createMarshaller();    20.         marshaller.marshal(customer, doc);    21.             22.         DOMSource domSource = new DOMSource(doc);    23.         StringWriter writer = new StringWriter();    24.         StreamResult result = new StreamResult(writer);    25.         TransformerFactory tf = TransformerFactory.newInstance();    26.         Transformer transformer = tf.newTransformer();    27.         transformer.transform(domSource, result);    28.         String xmlString = writer.toString();    29.         System.out.println(xmlString);    30.         //XML转换成Java对象    31.         Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();    32.         StringReader reader = new StringReader(xmlString);    33.         Customer cus = (Customer)unmarshaller.unmarshal(reader);    34.         System.out.println("Age:"+cus.getAge());    35.         System.out.println("Name:"+cus.getName());    36.             37.             38.     }    39. }   public class SoapClient { private final static String MODEL = "com.itdcl.model"; public static void main(String[] args) throws ParserConfigurationException, JAXBException, TransformerException{ ObjectFactory factory = new ObjectFactory(); Customer customer = factory.createCustomer(); customer.setAge(20); customer.setName("Josen"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); JAXBContext jaxbContext = JAXBContext.newInstance(MODEL); //Java对象转换成XML Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.marshal(customer, doc); DOMSource domSource = new DOMSource(doc); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String xmlString = writer.toString(); System.out.println(xmlString); //XML转换成Java对象 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); StringReader reader = new StringReader(xmlString); Customer cus = (Customer)unmarshaller.unmarshal(reader); System.out.println("Age:"+cus.getAge()); System.out.println("Name:"+cus.getName()); } }       第三步,运行一个测试类,看看效果如何。Java与XML之间转换如此简单       编组操作:利用上面生成的java文件执行编组操作。 Java代码 1. JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);    2. //Java对象转换成XML    3.               Marshaller marshaller = jaxbContext.createMarshaller();    4. marshaller.marshal(customer, doc);    5.    6. DOMSource domSource = new DOMSource(doc);    7. StringWriter writer = new StringWriter();    8. StreamResult result = new StreamResult(writer);    9. TransformerFactory tf = TransformerFactory.newInstance();    10. Transformer transformer = tf.newTransformer();    11. transformer.transform(domSource, result);    12. String xmlString = writer.toString();    13. System.out.println(xmlString);   JAXBContext jaxbContext = JAXBContext.newInstance(MODEL); //Java对象转换成XML Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.marshal(customer, doc); DOMSource domSource = new DOMSource(doc); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String xmlString = writer.toString(); System.out.println(xmlString);      解组操作:通过xml文件执行解组操作。     Java代码 1.               JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);    2.               Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();    3. StringReader reader = new StringReader(xmlString);    4. Customer cus = (Customer)unmarshaller.unmarshal(reader);    5. System.out.println("Age:"+cus.getAge());    6. System.out.println("Name:"+cus.getName());   JAXBContext jaxbContext = JAXBContext.newInstance(MODEL); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); StringReader reader = new StringReader(xmlString); Customer cus = (Customer)unmarshaller.unmarshal(reader); System.out.println("Age:"+cus.getAge()); System.out.println("Name:"+cus.getName());     也可通过Ant配置来解组,如下: Java代码 1.    2.    3.         4.         5.         6.         7.         8.    9.         10.             11.         12.         14.             15.         16.             17.             19.                 20.             21.         22.    WebService CXF学习(高级篇1):整合Spring框架 通过前面两节的讲解,相信你对CXF框架开始有一些认识了。在当今项目开发中,Spring框架基上都用到过,那么它怎么与CXF结合呢,这就是我们这一间要讲的内容。好了,闲话少说。     首先,在前面基础上再导入几个spring要用到的几个.jar包:     spring-core.jar     spring-jdbc.jar     spring-context.jar     spring-orm.jar     spring-beans.jar     spring-tx.jar     包导入完之后,我们还不能开如干活,配置几荐参数,便于下一步工作。     配置CXF框架     我的电脑->属性->高级->环境变量     创建一个CXF_HOEM变量,值为CXF框架所在根目录,修改一下     CLASSPATH=%CXF_HOME%/lib;PATH=%CXF_HOME%/bin;这时有会问为什么要配置这两个参数据呢,其实配置这两个参数用途与配置JAVA变量一下,在DOS窗口下直接运行java2ws,wsdl2java等可执行文件。当然你没有配置也可以进到CXF框架的bin目录下远行这个几个可执行文件。    配置好了后,你在DOS窗口下输入java2ws,看看配置是否效。肯定没有成功,原因是使用6.0的JDK,我们还得在%JAVA_HOME%/jre/lib目录下创建一下endorsed文件夹,将jaxb-api.jar,jaxws.jar拷贝进去。现在再运一下java2ws,成功运行,配置生效了。     基本工作做得差不多,整合spring框架正式开始:     第一步:新一个web project,导入要用到.jar包,其实CXF利用org.apache.cxf.transport.servlet.CXFServlet来拦截所有web请求,将其配置到web.xml中。配置如下: Java代码 1.    2.         3.         contextConfigLocation    4.             5.             /WEB-INF/classes/applicationContext-*.xml,/WEB-INF/classes/webservice.xml    6.             7.         8.    9.         10.             11.             org.springframework.web.context.ContextLoaderListener    12.             13.         14.    15.     [color=red]    16.         CXFServlet    17.         CXF Servlet    18.             19.             org.apache.cxf.transport.servlet.CXFServlet    20.             21.         1    22.         23.    24.         25.         CXFServlet    26.         /*    27.     [/color]    28.    contextConfigLocation /WEB-INF/classes/applicationContext-*.xml,/WEB-INF/classes/webservice.xml org.springframework.web.context.ContextLoaderListener [color=red] CXFServlet CXF Servlet org.apache.cxf.transport.servlet.CXFServlet 1 CXFServlet /* [/color]       注意一下绿色字体       CXF框架配置好了,我就来开发一个WebService接口 Java代码 1.      @WebService   2.      public interface IService {    3.    4. //public void save(@WebParam(name="info")String xml);    5. public void save(@WebParam(name="dto")UserInfoDTO dto,@WebParam(name="flag")boolean flag);    6. public void update(@WebParam(name="info")String xml);    7. public void delete(@WebParam(name="id")int id);    8. public @WebResult(name="String")String get(@WebParam(name="id")int id);    9.     }   @WebService public interface IService { //public void save(@WebParam(name="info")String xml); public void save(@WebParam(name="dto")UserInfoDTO dto,@WebParam(name="flag")boolean flag); public void update(@WebParam(name="info")String xml); public void delete(@WebParam(name="id")int id); public @WebResult(name="String")String get(@WebParam(name="id")int id); }     这里面有四个方法,其中有一个涉及到对象,这一点前面一节讲到怎么处理它。放在这里是再回顾前节内容。     创建一个WebService接口实现类     Java代码 1.    @WebService   2.    public class ServiceImpl implements IService {    3. private Logger log = LoggerFactory.getLogger(ServiceImpl.class);    4.    5. public void delete(int id) {    6.     log.info("delete id is {} user"+id);    7. }    8.    9. public void save(UserInfoDTO dto,boolean flag) {    10.     System.out.println("name:"+dto.getName());    11. }    12.    13. public void update(String xml) {    14. }    15.    16. public String get(int id){    17.     return null;    18. }    19.   }    20.       @WebService public class ServiceImpl implements IService { private Logger log = LoggerFactory.getLogger(ServiceImpl.class); public void delete(int id) { log.info("delete id is {} user"+id); } public void save(UserInfoDTO dto,boolean flag) { System.out.println("name:"+dto.getName()); } public void update(String xml) { } public String get(int id){ return null; } }    由于本节只讲解与Spring整合,没有涉及到数据库,因就打印一下传递过来的对象内容来证明整合成功。与spring,hibernate整合后面章节会讲到,请留意后面章节。    传递对象,当然创建对象啦 Java代码 1.   @XmlType(name="ServerUserInfo")    2.   @XmlAccessorType(XmlAccessType.FIELD)    3.   public class UserInfoDTO implements java.io.Serializable {    4.    5. private static final long serialVersionUID = -4666026219400887433L;    6. private Integer id;    7. private String name;    8. private Integer age;    9. private Integer address;    10.    11. public Integer getId() {    12.     return id;    13. }    14.    15. public void setId(Integer id) {    16.     this.id = id;    17. }    18.    19. public String getName() {    20.     return name;    21. }    22.    23. public void setName(String name) {    24.     this.name = name;    25. }    26.    27. public Integer getAge() {    28.     return age;    29. }    30.    31. public void setAge(Integer age) {    32.     this.age = age;    33. }    34.    35. public Integer getAddress() {    36.     return address;    37. }    38.    39. public void setAddress(Integer address) {    40.     this.address = address;    41. }    42.    43. public UserInfoDTO() {    44. }    45.    46.    }   @XmlType(name="ServerUserInfo") @XmlAccessorType(XmlAccessType.FIELD) public class UserInfoDTO implements java.io.Serializable { private static final long serialVersionUID = -4666026219400887433L; private Integer id; private String name; private Integer age; private Integer address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Integer getAddress() { return address; } public void setAddress(Integer address) { this.address = address; } public UserInfoDTO() { } }    做了这么多工作,有人又会问,怎么现在做的与spring框架就没一点联系,呵呵,确实是这样。开戏开场了,利用Spring来发布WebService接口: Java代码 1.    2.    10.     [color=red]    11.             12.             13.         14.     [/color]    15.    16.             17.         19.             20.         21.    [color=red] [/color]      服务端开发工作基本结束。现在打包部署到Tomcat6.0.18(本人目前使用的测试服务器,你当然可以使用别的服务器)     服务器启动完成后,打开浏览器在地址栏中输入http://localhost:port/project name/Service?wsdl看看接口是否发成功。     接下来就是开发一个客户端了。     另建一个web project,现在前面的参数配置要起作用了,cmd进入DOS环境下输入wsdl2java -p com.itdcl.service(自定义包名) http://localhost:port/project name/Service?wsdl(前提是服务器没停止)     敲击Enter,wsdl2java工具帮你将发布出来的wsdl文件转换成webservice接口,到指定目录下将com.itdcl.service拷到刚才另建的web project的src目录下。     现在,我们就来创建一个客户端程序: Java代码 1.     public class SampleClient {    2.    3. ublic static void main(String[] args) {    4. ApplicationContext context = new ClassPathXmlApplicationContext(    5.         "beans.xml");    6.       7.  IService service = (IService)context.getBean("service");    8.  ServerUserInfo userInfo = new ServerUserInfo();    9.  userInfo.setAddress(1);    10.  userInfo.setAge(100);    11.  userInfo.setName("Jason");    12.    13.  service.save(userInfo,true);    14.  service.delete(1);    15.    16.    17.  }   public class SampleClient { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans.xml"); IService service = (IService)context.getBean("service"); ServerUserInfo userInfo = new ServerUserInfo(); userInfo.setAddress(1); userInfo.setAge(100); userInfo.setName("Jason"); service.save(userInfo,true); service.delete(1); } }     看得仔细的朋友就会问了,ServerUserInfo 这个类那来的,你进到com.itdcl.service目录下就会看到,是WebService发布出来的。     到目前为止,客户端还没有完成,你没有看到程序中ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");这个bean.xml就是spring框架来注删除WebService接口的。好啦,创建一个bean.xml,内容如下: Java代码 1.       2.       10.    13.          留意一下绿色字体     剩下的事就是运行客户端程序了,没有异常抛出,打印出:name:Josen,则恭喜你CXF框架与Spring整合成功。 WebService CXF学习(高级篇2):CXF+Spring+Hibernate 前一节仅仅只讲了与Spring整合,没有涉及到数据库,而且是直接将Java象传递到服务端。这一节我起到一个回顾前面章节的作用。用在客户端运用JABX将JAVA对象编组成XML文件,在客户端将XML解组成JAVA并存入数据库。下面我们就着手开发这个Demo:     服务端开发     第一步,编写数据资源层相关接口     DAO编写:     Java代码 1. public interface HibernateDao {    2.         3.     public void save(UserInfo object);    4.     public void delete(UserInfo object);    5.     public void update(UserInfo object);    6.     public UserInfo get(int id);    7. }    8.        public interface HibernateDao { public void save(UserInfo object); public void delete(UserInfo object); public void update(UserInfo object); public UserInfo get(int id); }     DAO实现类: Java代码 1. public class HibernateDaoImpl extends HibernateDaoSupport implements HibernateDao {    2.    3.     public void delete(UserInfo object) {    4.         this.getHibernateTemplate().delete(object);    5.     }    6.    7.     public void save(UserInfo object) {    8.         this.getHibernateTemplate().save(object);    9.     }    10.    11.     public void update(UserInfo object) {    12.         this.getHibernateTemplate().update(object);    13.     }    14.    15.     public UserInfo get(int id) {    16.         return (UserInfo) this.getHibernateTemplate().get(UserInfo.class, id);    17.     }    18.    19. }   public class HibernateDaoImpl extends HibernateDaoSupport implements HibernateDao { public void delete(UserInfo object) { this.getHibernateTemplate().delete(object); } public void save(UserInfo object) { this.getHibernateTemplate().save(object); } public void update(UserInfo object) { this.getHibernateTemplate().update(object); } public UserInfo get(int id) { return (UserInfo) this.getHibernateTemplate().get(UserInfo.class, id); } }       实体对象: Java代码 1. @Entity   2. @Table(name = "userinfo")    3. public class UserInfo implements java.io.Serializable {    4.    5.     private static final long serialVersionUID = 2281022190032353574L;    6.         7.     @Id   8.     @GeneratedValue(strategy = GenerationType.IDENTITY)    9.     private Integer id;    10.     private String name;    11.     private Integer age;    12.     private Integer address;    13.    14.     public UserInfo() {    15.     }    16.    17.     public UserInfo(String name, Integer age) {    18.         this.name = name;    19.         this.age = age;    20.     }    21.    22.     public UserInfo(String name, Integer age, Integer address) {    23.         this.name = name;    24.         this.age = age;    25.         this.address = address;    26.     }    27.    28.     public Integer getId() {    29.         return this.id;    30.     }    31.    32.     public void setId(Integer id) {    33.         this.id = id;    34.     }    35.    36.     public String getName() {    37.         return this.name;    38.     }    39.    40.     public void setName(String name) {    41.         this.name = name;    42.     }    43.    44.     public Integer getAge() {    45.         return this.age;    46.     }    47.    48.     public void setAge(Integer age) {    49.         this.age = age;    50.     }    51.    52.     public Integer getAddress() {    53.         return this.address;    54.     }    55.    56.     public void setAddress(Integer address) {    57.         this.address = address;    58.     }    59.    60. }   @Entity @Table(name = "userinfo") public class UserInfo implements java.io.Serializable { private static final long serialVersionUID = 2281022190032353574L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private Integer age; private Integer address; public UserInfo() { } public UserInfo(String name, Integer age) { this.name = name; this.age = age; } public UserInfo(String name, Integer age, Integer address) { this.name = name; this.age = age; this.address = address; } public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Integer getAge() { return this.age; } public void setAge(Integer age) { this.age = age; } public Integer getAddress() { return this.address; } public void setAddress(Integer address) { this.address = address; } }       第二步:业务逻辑层接口编写       业务逻辑接口: Java代码 1. @WebService   2. public interface IService {    3.    4.     //public void save(@WebParam(name="info")String xml);    5.     public void save(@WebParam(name="dto")UserInfoDTO dto,@WebParam(name="flag")boolean flag);    6.     public void update(@WebParam(name="info")String xml);    7.     public void delete(@WebParam(name="id")int id);    8.     public @WebResult(name="String")String get(@WebParam(name="id")int id);    9. }   @WebService public interface IService { //public void save(@WebParam(name="info")String xml); public void save(@WebParam(name="dto")UserInfoDTO dto,@WebParam(name="flag")boolean flag); public void update(@WebParam(name="info")String xml); public void delete(@WebParam(name="id")int id); public @WebResult(name="String")String get(@WebParam(name="id")int id); }      接口实现类: Java代码 1. @WebService   2. public class ServiceImpl implements IService {    3.     private Logger log = LoggerFactory.getLogger(ServiceImpl.class);    4.     private HibernateDao dao;    5.         6. //  public void setDao(HibernateDao dao) {    7. //      this.dao = dao;    8. //  }    9.    10.     public void delete(int id) {    11.         log.info("delete id is {} user"+id);    12.         //UserInfo userInfo = (UserInfo)object;    13.         //log.info("this username is:"+userInfo.getName());    14.         //log.info("delete {} information..."+userInfo.getName());    15.         //dao.delete(userInfo);    16.     }    17.    18. //  public void save(String xml) {    19. //      //UserInfo userInfo = (UserInfo)object;    20. //      log.info("add {} user..."+xml);    21. //      //dao.save(userInfo);    22. //      System.out.println("ssss");    23. //  }    24.         25.     public void save(UserInfoDTO dto,boolean flag) {    26.         System.out.println("name:"+dto.getName());    27.     }    28.    29.     public void update(String xml){    30.         ApplicationContext context = new ClassPathXmlApplicationContext(    31.         "applicationContext-resources.xml");    32.         this.dao = (HibernateDao)context.getBean("dao");    33.         try {    34.             JAXBContext jaxbContext = JAXBContext.newInstance("com.itdcl.model");    35.             Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();    36.             StringReader reader = new StringReader(xml);    37.             Customers cus = (Customers)unmarshaller.unmarshal(reader);    38.             Customer cust = cus.getCustomer();    39.                 40.             UserInfo userInfo = new UserInfo();    41.             System.out.println("Address:"+cust.getAddress());    42.             userInfo.setAddress(cust.getAddress());    43.             System.out.println("Age:"+cust.getAge());    44.             userInfo.setAge(Integer.valueOf(cust.getAge()));    45.             System.out.println("Name:"+cust.getName());    46.             //userInfo.setId(2);    47.             userInfo.setName(cust.getName());    48.                 49.             dao.save(userInfo);    50.         } catch (JAXBException e) {    51.             e.printStackTrace();    52.         }    53.             54.     }    55.         56.     public String get(int id){    57.         //return dao.get(id);    58.         return null;    59.     }    60. }   @WebService public class ServiceImpl implements IService { private Logger log = LoggerFactory.getLogger(ServiceImpl.class); private HibernateDao dao; // public void setDao(HibernateDao dao) { // this.dao = dao; // } public void delete(int id) { log.info("delete id is {} user"+id); //UserInfo userInfo = (UserInfo)object; //log.info("this username is:"+userInfo.getName()); //log.info("delete {} information..."+userInfo.getName()); //dao.delete(userInfo); } // public void save(String xml) { // //UserInfo userInfo = (UserInfo)object; // log.info("add {} user..."+xml); // //dao.save(userInfo); // System.out.println("ssss"); // } public void save(UserInfoDTO dto,boolean flag) { System.out.println("name:"+dto.getName()); } public void update(String xml){ ApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext-resources.xml"); this.dao = (HibernateDao)context.getBean("dao"); try { JAXBContext jaxbContext = JAXBContext.newInstance("com.itdcl.model"); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); StringReader reader = new StringReader(xml); Customers cus = (Customers)unmarshaller.unmarshal(reader); Customer cust = cus.getCustomer(); UserInfo userInfo = new UserInfo(); System.out.println("Address:"+cust.getAddress()); userInfo.setAddress(cust.getAddress()); System.out.println("Age:"+cust.getAge()); userInfo.setAge(Integer.valueOf(cust.getAge())); System.out.println("Name:"+cust.getName()); //userInfo.setId(2); userInfo.setName(cust.getName()); dao.save(userInfo); } catch (JAXBException e) { e.printStackTrace(); } } public String get(int id){ //return dao.get(id); return null; } }      DAO与Service接口配置: Java代码 1.    2.    13.    14.         15.         17.             18.                 19.                 classpath:jdbc.properties    20.                 21.             22.         23.    24.         26.             27.             28.             29.             30.         31.    32.         34.             35.                 36.             37.             38.                 39.                     40.                     ${hibernate.dialect}    41.                     42.                 ${show_sql}    43.                 ${format_sql}    44.                     45.                     46.                     ${cache.use_query_cache}    47.                     48.                     49.                     ${cache.use_second_level_cache}    50.                     51.                     52.                     ${cache.provider_class}    53.                     54.    55.                     56.                     57.                     ${c3p0.acquire_increment}    58.                     59.                     60.                     ${c3p0.max_statements}    61.                     62.                 ${c3p0.min_size}    63.                 ${c3p0.max_size}    64.                 ${c3p0.timeout}    65.                     66.                     ${c3p0.idle_test_period}    67.                     68.                 69.             70.             71.                 72.             73.             74.         75.    76.         77.             78.         79.    classpath:jdbc.properties ${hibernate.dialect} ${show_sql} ${format_sql} ${cache.use_query_cache} ${cache.use_second_level_cache} ${cache.provider_class} ${c3p0.acquire_increment} ${c3p0.max_statements} ${c3p0.min_size} ${c3p0.max_size} ${c3p0.timeout} ${c3p0.idle_test_period}      WebService接口发布: Java代码 1.    2.    10.         11.         12.         13.    14.         15.         17.    18.         20.    21.         23.             26.         27.    28.         30.             31.             32.         33.    34.         36.        第三步:服务端程序编写了,打包部署     客户端开发     第一步:WebService客户端生成,可以手工编写。这里我就通过配置Ant文件来生成WebService客户端: Java代码 1.    2.    3.         4.         5.         6.         7.         8.         9.         10.         11.    12.         13.             15.             17.         18.         19.             20.             21.                 22.                 23.             24.             25.             26.                 27.                     28.                 29.             30.         31.    32.         33.             34.             35.             36.                 37.                 38.                 39.                 40.                 41.             42.         43.        第二步:WebService接口注册配置 Java代码 1.    2.    10.    11.         14.    15.         18.    19.         22.             剩下的事就测试我们整合是否成功了,编写一个JUnit测试类或写一个Main函数测试一下。 Java代码 1. public class JaxbSampleClient {    2.     private final static String MODEL = "com.itdcl.model";    3.     public static void main(String[] args) throws FileNotFoundException, JAXBException, ParserConfigurationException, TransformerException {    4.         ApplicationContext context = new ClassPathXmlApplicationContext(    5.                 "beans.xml");    6.         IService service = (IService) context.getBean("service");    7.             8.             9.         ObjectFactory factory = new ObjectFactory();    10.         Customer customer = factory.createCustomer();    11.         customer.setId(1);    12.         customer.setAge("26");    13.         customer.setName("Josen");    14.         customer.setAddress(100);    15.    16.         Customers customers = factory.createCustomers();    17.         customers.setCustomer(customer);    18.    19.         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();    20.         dbf.setNamespaceAware(true);    21.         DocumentBuilder db = dbf.newDocumentBuilder();    22.         Document doc = db.newDocument();    23.    24.         // 转换    25.         JAXBContext jaxbContext = JAXBContext.newInstance(MODEL);    26.         Marshaller marshaller = jaxbContext.createMarshaller();    27.         //将customers数据与doc绑定    28.         marshaller.marshal(customers, doc);    29.             30.         DOMSource domSource = new DOMSource(doc);    31.         StringWriter writer = new StringWriter();    32.         StreamResult result = new StreamResult(writer);    33.         TransformerFactory tf = TransformerFactory.newInstance();    34.         Transformer transformer = tf.newTransformer();    35.         transformer.transform(domSource, result);    36.         String xmlString = writer.toString();    37.         //System.out.println(xmlString);    38.             39.         service.update(xmlString);    40.     }    41.    42. }  public class JaxbSampleClient { private final static String MODEL = "com.itdcl.model"; public static void main(String[] args) throws FileNotFoundException, JAXBException, ParserConfigurationException, TransformerException { ApplicationContext context = new ClassPathXmlApplicationContext( "beans.xml"); IService service = (IService) context.getBean("service"); ObjectFactory factory = new ObjectFactory(); Customer customer = factory.createCustomer(); customer.setId(1); customer.setAge("26"); customer.setName("Josen"); customer.setAddress(100); Customers customers = factory.createCustomers(); customers.setCustomer(customer); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); // 转换 JAXBContext jaxbContext = JAXBContext.newInstance(MODEL); Marshaller marshaller = jaxbContext.createMarshaller(); //将customers数据与doc绑定 marshaller.marshal(customers, doc); DOMSource domSource = new DOMSource(doc); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String xmlString = writer.toString(); //System.out.println(xmlString); service.update(xmlString); } } 运行一下,看插入数据库没有。这节到此就靠一段落啦,下节讲解WS-Security WebService CXF学习(高级篇3):WS-Security 这一节我们来探讨一下WebService安全问题,如果所有系统都运行在一个封闭的局域网内,那么可以不考虑网络攻击,拒绝服务,消息篡改,窃取等问题。但通常情况都接入互联网,那么我就得考虑信息安全问题,像前面那样直接将消息裸传,肯定不行。那么,我们就得给消息加密。CXF可以结合WSS4J来对消息安全进行管理,可以使用令牌,X.509认证对消息头或内容进行加密。这节我只对令牌加密做一个简单的描述,我们还以Demo的形式来讲解一下。     这个Demo是在CXF+Spring+Hibernate的基础修改而成。在这里我只针对修改的东西进行讲解。 Java代码 1.    2.    10.         11.         12.         13.    14.    15.         17.             18.                 20.                 22.                 24.                     25.                         26.                             27.                             29.                             30.                             31.                                 32.                             33.                         34.                     35.                 36.             37.         38.    39.         41.    42.        action:UsernameToken指使用用户令牌     passwordType:PasswordText指密码加密策略,这里直接文本     user:cxfServer指别名     passwordCallBackRef:serverPasswordCallback指消息验证     消息验证类: Java代码 1. package com.itdcl.ws;    2.    3. import java.io.IOException;    4.    5. import javax.security.auth.callback.Callback;    6. import javax.security.auth.callback.CallbackHandler;    7. import javax.security.auth.callback.UnsupportedCallbackException;    8.    9. import org.apache.ws.security.WSPasswordCallback;    10.    11. public class ServerPasswordCallback implements CallbackHandler {    12.    13.     public void handle(Callback[] callbacks) throws IOException,    14.             UnsupportedCallbackException {    15.         WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];    16.         String pw = pc.getPassword();    17.         String idf = pc.getIdentifier();    18.         System.out.println("password:"+pw);    19.         System.out.println("identifier:"+idf);    20.         if (pw.equals("josen") && idf.equals("admin")) {    21.             // 验证通过    22.         } else {    23.             throw new SecurityException("验证失败");    24.         }    25.     }    26.    27. }   package com.itdcl.ws; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class ServerPasswordCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; String pw = pc.getPassword(); String idf = pc.getIdentifier(); System.out.println("password:"+pw); System.out.println("identifier:"+idf); if (pw.equals("josen") && idf.equals("admin")) { // 验证通过 } else { throw new SecurityException("验证失败"); } } }      消息验证类通过实现CallbackHandler接口,实现handle方法来进行用户认证。      那么,客户端又怎样来验证消息是否确呢。 Java代码 1.    2.    10.    11.         14.             15.                 17.                 19.                 21.                     22.                         23.                             24.                             26.                             27.                             28.                                 29.                             30.                         31.                     32.                 33.             34.         35.    36.         38.        客户端在发送SOAP时对消息对认证,策略跟服务端一样。但是认证类有所区别: Java代码 1. package com.itdcl.ws;    2.    3. import java.io.IOException;    4.    5. import javax.security.auth.callback.Callback;    6. import javax.security.auth.callback.CallbackHandler;    7. import javax.security.auth.callback.UnsupportedCallbackException;    8.    9. import org.apache.ws.security.WSPasswordCallback;    10.    11. public class ClientPasswordCallback implements CallbackHandler {    12.    13.     public void handle(Callback[] callbacks) throws IOException,    14.             UnsupportedCallbackException {    15.         for(int i=0;i trainList = null;    45.          FileInputStream fi = null;    46.          try {    47.              fi = new FileInputStream(path);    48.              trainList = new ArrayList();    49.              SAXBuilder sb = new SAXBuilder();        50.              Document doc = sb.build(fi);        51.              Element root = doc.getRootElement(); // 得到根元素        52.              List focs = root.getChildren();    53.              Element foc = null;    54.              Train train = null;    55.                  56.              for(int i=0; i trainList = null; FileInputStream fi = null; try { fi = new FileInputStream(path); trainList = new ArrayList(); SAXBuilder sb = new SAXBuilder(); Document doc = sb.build(fi); Element root = doc.getRootElement(); // 得到根元素 List focs = root.getChildren(); Element foc = null; Train train = null; for(int i=0; iApache-Axis    2.    3.   Apache-Axis Servlet    4.   AxisServlet    5.       6.       org.apache.axis.transport.http.AxisServlet    7.       8.    9.    10.   Axis Admin Servlet    11.   AdminServlet    12.       13.       org.apache.axis.transport.http.AdminServlet    14.       15.   100    16.    17.    18.   AxisServlet    19.   /services/*    20.    Apache-Axis Apache-Axis Servlet AxisServlet org.apache.axis.transport.http.AxisServlet Axis Admin Servlet AdminServlet org.apache.axis.transport.http.AdminServlet 100 AxisServlet /services/* 3.用axis发布webservice的方法 用axis发布webservice的方法有3种: 1)即时发布 编译好类文件,把扩展名改成jws,然后放到axis的目录下,因为axis目录下默认有web.xml定义,用org.apache.axis.transport.http.AxisServlet来解析*.jws文件。 2)手动发布     也就是写部署文件deploy.wsdd,这个文件里已经写了入口地址,运行java org.apache.axis.client.AdminClient即可完成部署. 访问的时候一般是http://127.0.0.1:8080/axis/services/入口地址. 3)自动部署    要编写server-config.wsdd,配置web.xml,发布和普通的web程序发布一样,入口地址也已经写到server-config.wsdd里了,查看的时候就是http://127.0.0.1:8080/你的发布webapp/services/入口地址    Java类映射到WSDL的规则,请参考JAX-RPC规范    服务发布以后,就可以在IE浏览器里看到它的WSDL,一般是服务的URL后面加一个“?wsdl” 4.AXIS的几种服务类型      AXIS有四种service styles,分别是:RPC, Document, Wrapped, 和Message。最常用的就是RPC和Message。 1)RPC服务    这个服务是axis默认的服务。我们在前面的例子中写的就是rpc服务。 。rpc服务遵从soap rpc规范和编码规则,意味着来自rpc服务的xml将类似上面例子中的“echoString”--每个rpc调用被模块化为一个外部元素,匹配操作名称,并包含了很多内部元素,每一个都是操作的一个参数。axis将把这些xml转化为java对象,配送给你得服务,并将序列化来自服务的java对象为xml.因为rpc服务默认采用soap section 5规则,对象将会通过"multi-ref" 序列化来编码。 2)Document / Wrapped 服务 这2个服务很类似,都不需要用soap编码来处理数据。他就是一个普通的xml格式。无论哪种情况,axis还是对他们做了xml到java得绑定,所以你最终处理的还是java对象,而不是xml结构的字符串。   下面的例子来说明他们2个之间的区别。 Java代码 1.    3.      4.        5.      SK001    6.      1    7.      Sushi Knife    8.        9.      10. lt;/soap:Envelope>   SK001 1 Sushi Knife 相关的PurchaseOrder类型定义如下: Java代码 1.    2.       3.         4.           5.           6.           7.         8.       9.       10.    对于一个document服务来说,他将对应到这样的方法: public void method(PurchaseOrder po) 而对于wrapped服务来说,他对应于下面的方法: public void purchaseOrder(String item, int quantity, String description) 3)Message 服务   当你需要处理纯xml而不是java对象时,你将会用到这种服务。   message服务的方法有4种签名 Java代码 1. public Element [] method(Element [] bodies);    2. public SOAPBodyElement [] method (SOAPBodyElement [] bodies);    3. public Document method(Document body);    4. public void method(SOAPEnvelope req, SOAPEnvelope resp);   public Element [] method(Element [] bodies); public SOAPBodyElement [] method (SOAPBodyElement [] bodies); public Document method(Document body); public void method(SOAPEnvelope req, SOAPEnvelope resp); 5.axis生成web service客户端的调用框架 用Axis的wsdl2java生成Web service的客户端的调用框架,wsdl2java生成的客户端的调用框架是stub方式的。它包括endpoint接口、实现该接口的stub,serviceLocator.通过服务端提供WSDL信息来生成客户端的调用框架.   有了web service客户端的调用框架,客户端stub存根方式调用web服务 HTTP/1.1 200 OK Content-Type: application/soap+xml; charset=utf-8 Content-Length: nnn 34.5

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享文档获得金币 ] 9 人已下载

下载文档