前言java
今天主要讲解下WebService的两个流行的框架Axis和CXF。web
正题apache
1、服务端发布WebService浏览器
在讲解以前,咱们先来看一下这篇博客主要讲解的内容:tomcat
每一种框架都有本身的特色,有本身的侧重,可是他们的共同之处在于对发布WebService进行了封装,因此咱们只需编写一个配置文件或者使用@WebService 注解就能够发布WebService,咱们这里着重说一下他们各自的特色:服务器
1.Axis1网络
Axis1有两种发布方式:app
1)JWS方式框架
a.这种方式很简单,只须要将源码java文件放到AXIS_HOME下面,而后将后缀改成.jws,这样,Axis 会自动编译.jws文件,并把它自动加入到Java WebServie的服务中。webapp
b.可是这种方式的缺点是:只能是java源代码,同时类中不能含有包名。
2)WSDD方式
1.写一个java类(须要引入axis的jar包)
2.配置web.xml文件(配置AxisServlet,AdminServlet,SOAPMonitorService和AxisHTTPSessionListener)
3.写一个deloy.wsdd文件,部署项目(tomcat启动就能够部署项目)
安装axis1到tomcat:
1.Axis官方网站:http://ws.apache.org/axis/,能够在官网下载最新1.4的包:axis-bin-1_4.zip
2.将解压后的axis-1_4\webapps\下的axis目录考到%TOMCAT_HOME%/Webapps/目录下
3.启动tomcat后在浏览器里输入http://localhost:port/axis
4.点击上图中的Validataion连接,页面上会提示已经有的包和缺乏的包的信息,根据提示将必须的包下载全,
将这些类包复制到%tomcathome%/webapps/axis/WEB-INF/lib/目录下
从新启动tomcat,直到Validation页面中看不到有Error与Warning的提示信息。
2.Axis2
客户端对于数据类型的不一样有两种调用方式:RPCServiceClient和OMAbstractFactory方式
1)RPC方式:
处理基本的数据类型,如String,int等
2)OM方式:
可处理基本数据类型和自定义数据类型(好比java实体对象):经过xml的参数形式进行传递(传递的参数须要转换为OMElement)
注:若是参数或返回值是List类型则须要进行手动处理转换(手动编写一个服务端对传递过来的参数进行处理,将传过来的OMElement手动转换为List类型,调用执行方法,而后将返回的List类型再转换为OMElement传回客户端)
Axis2发布文件(编写services.xml)
1.将官网下载的axis2.war包拷贝到tomcat_home/webapps下,运行即会解压
2.将其conf,modules和services文件夹拷贝到项目的WEB-INF下面,并将lib下的jar包拷贝到web-inf/lib下面
3.配置Web.xml(配置AxisServlet和AxisAdminServlet)
4.编写services下面的services.xml文件,指定要发布的类
3.CXF
CXF发布WebService有三种方式:main方式,基于和不基于Spring发布到容器
1)main方式
引入jar包,在接口和实现类上使用@WebService 便可,发布完成后便可在浏览器中访问url,不须要启动tomcat等服务。
2)不基于Spring方式发布到容器
a)引入cxf的jar包,编写web.xml(配置自定义的CXFServlet,该CXFServlet须要继承CXFNonSpringServlet)
b)编写实体类,业务类和服务类(实体类须要和服务类在同一包下,不然报错)
c)启动Tomcat,便可发布服务
3)基于Spring方式发布到容器
a)web.xml配置(Spring配置,cxf封装的CXFServlet配置)
b)applicationContext-server.xml配置
<!--Import apache CXF bean definition 固定-->
<importresource="classpath:META-INF/cxf/cxf.xml" />
<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<importresource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!--services接口配置 -->
<beanid="helloServicesBean"class="com.ms.services.impl.HelloServicesImpl" />
<!--CXF 配置WebServices的服务名及访问地址 -->
<jaxws:serverid="helloServices" address="/HelloServices"
serviceClass="com.ms.services.IHelloServices">
<!--要暴露的webservice服务 -->
<jaxws:serviceBean>
<refbean="helloServicesBean"/>
</jaxws:serviceBean>
</jaxws:server>
c)编写类
实体类
服务接口(类头使用@WebService)
服务实现(类头使用@WebService(endpointInterface="com.ms.services.IHelloServices"))
以上是关于Axis和CXF发布特色及其须要注意的地方,是我作例子时的总结,有兴趣的同窗能够下载源码。
2、客户端调用WebService
服务端将接口发布成功后,就等着客户端来进行调用了,客户端如何并经过什么方式来调用咱们服务端发布的wsdl文件呢?
1.调用一次WebService的本质:
1.客户端把调用方法参数,转换生成XML文档片断(SOAP消息,input消息,该文档片断必须符合WSDL定义的格式),经过网络,把XML文档片断传给服务器
2.服务器接收到XML文档片断,解析XML文档片断,提取其中的数据,并把数据转换调用WebService所须要的参数值。
3.服务器执行方法。
4.把执行方法获得的返回值,再次转换生成为XML文档片断(SOAP消息,output消息)——该文档片断必须符合WSDL定义的格式,经过网络,把XML文档片断传给客户端。
5.客户端接收到XML文档片断,解析XML文档片断,提取其中数据,并把数据转换调用WebService的返回值。
从上面调用本质来看,要一个语言支持WebService,惟一的要求是:该语言支持XML文档解析、生成、支持网络传输。
2.客户端调用方式:
客户端调用服务端方法整体来讲有三种方式:
1)DII(Dynamic Invocation Interface)
采用直接调用方式,能够在程序中设置诸多的调用属性,使用较为灵活,可是调用过程却相对繁琐复杂,易形成代码膨胀且可重用性低,每次调用不一样的Web Service都要重复进行大量编码。
这也是咱们比较经常使用的一种方法,就是调用invoke方法,传入方法名和方法参数便可。
2)Stubs
JAX-RPC使用静态的Stub方式包装对底层接口的调用,从而提供一种更为简便的调用方式。使用该方式须要利用支持环境(好比Axis)所提供的工具根据WSDL预生成WebService客户端的实现代码。所以若是服务的WSDL发生变化,就必须从新生成新的客户端代码并进行从新部署。
该方法须要使用wsdl2java命令来预生成WebService客户端代码,为了支持该命令,须要安装一些环境。
3)Dynamic Proxy
动态代理(Dynamic Proxy)的方法实现对Web Service的动态调用,能够在运行时根据用户定义的Client端接口建立适配对象。从而避免了直接操做底层的接口,减小了客户端的冗余,屏蔽了调用相关的复杂性。
该方法主要在于客户端接口,该客户端接口须要继承java.rmi.Remote接口,而后将服务端的接口中的方法copy过来。
小结:
从发展历史角度来看,很容易理解他们的侧重点,Axis1最先,因此注重的只是简单的发布接口便可,以后随之Axis2对其进行了优化,能够支持自定义参数,但并不完善,因此CXF的出现对这一功能进行了完善而且适应了潮流,实现了与Spring的集成,跟这些比起来,EJB3中对于WebService的支持只须要使用一个@WebService 便可完成,因此软件的开发是让使用者变傻,而咱们学习这些是为了理解其原理和本质。