webservice学习笔记,亲自运行成功的实例.直接把word格式的笔记贴
?
WebService学习笔记
?
?
?
??????
??????????????????????????????????????????????????????????????????????????????????????????????????????????????? ??????
?
Created by
?
?
?
?
?
?
?
?
?
?
?
1?????? WebService概念:1.1??? 术语(资料摘要)????????? web Service Web Service是使应用程序可以以与平台和编程语言无关的方式进行相互通信的一项技术。Web 服务是一个软件接口,它描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作。它使用基于 XML 语言的协议来描述要执行的操作或者要与另一个 Web 服务交换的数据。一组以这种方式交互的 Web 服务在面向服务的体系结构(Service-Oriented Architecture,SOA)中定义了特殊的 Web 服务应用程序
?
?
????????? SOAP SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的轻量级协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一种语言相互通信。 SOAP包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例;SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。 应用中比较关注的是envelop,由一个或多个Header和一个Body组成。 SOAP在可互操作的基础 Web 服务协议栈中的位置:
?
?
????????? Axis Axis本质上就是一个SOAP引擎(Apache Axis is an implementation of the SOAP),提供创建服务器端、客户端和网关SOAP操作的基本框架。但Axis并不完全是一个SOAP引擎,它还包括: 是一个独立的SOAP服务器。 是一个嵌入Servlet引擎(例如Tomcat)的服务器。支持WSDL。 提供转化WSDL为Java类的工具。 提供例子程序。 提供TCP/IP数据包监视工具
?
????????? AXIS的几种服务类型 AXIS有四种service styles,分别是:RPC,Document,Wrapped,和Message。最常用的就是RPC和Message。
?
RPC:在AXIS中是一个默认选项。当你部署的时候使用下列两种方式: 或则 ,它遵循SOAP RPC和编码规则。每个RPC都包括一个表示名称的外部接点和一些表示参数的内部接点。AXIS会根据规则将一个XML(WSDL文件)文件转化成一个JAVA对象,并对对想赋上在文件中描述的值。也可以根据规则将一个JAVA对象转化成XML文件。
?
Document 适合于老的XML schema。
?
Wrapped
?
和DOCUMENT一样,适合于老的XML schema。 在大多书情况下,你不许要担心是DOCUMENT服务还是WRAPPED服务。
?
Message
?
以这种方式部署的话,会使AXIS失去意义,它使你的代码真正的用XML形式,而不需要转化成JAVA对象。以这种方式部署的有以下四种服务方法:
?
public Element [] method(Element [] bodies); public SOAPBodyElement [] method (SOAPBodyElement [] bodies); public Document method(Document body); public void method(SOAPEnvelope req,SOAPEnvelope resp);
?
几种服务类型的主要区别: 基于RPC(远程过程调用)方式,这也是Web服务最常用的方式。面向消息/文档的的类型跟RPC不同的是它提供了一个更底层的抽象,要求更多的编程工作。客户端可以传入任何的XML文档,得到的响应不一定是SOAPEnvelope,可以返回任何它所需要的东西,甚至不返回。虽然这对开发者来说非常的灵活,但是这种通讯类型在实际的应用中并不常见。面向消息/文档的Web服务主要适合于下面几种情况,比如批量处理,基于表单的数据导入,有需要返回非XML数据时,Web服务器实现中要求直接访问传输层等等
?
????????? WSDL Web服务的接口定义语言,由Ariba、Intel、IBM、MS等共同提出,通过WSDL,可描述Web服务的三个基本属性: ·服务做些什么——服务所提供的操作(方法) ·如何访问服务——和服务交互的数据格式以及必要协议 ·服务位于何处——协议相关的地址,如URL
?
WSDL文档以端口集合的形式来描述Web服务,WSDL 服务描述包含对一组操作和消息的一个抽象定义,绑定到这些操作和消息的一个具体协议,和这个绑定的一个网络端点规范。 WSDL在Web 服务概念性协议栈中的位置
?
????????? WSDD WSDD就是WEB服务分布描述(Web Service Deployment Descriptor),它定义了WEB服务的接口,如服务名、提供的方法、方法的参数等信息。
?
????????? UDDI UDDI就是统一描述、发现和集成(Universal Description,Discovery,and Integration)。UDDI用于集中存放和查找WSDL描述文件,起着目录服务器的作用。
?
Web 服务中的角色、操作和构件: ??? * 服务提供者。从企业的角度看,这是服务的所有者。从体系结构的角度看,这是托管访问服务的平台。 ??? * 服务请求者。从企业的角度看,这是要求满足特定功能的企业。从体系结构的角度看,这是寻找并调用服务,或启动与服务的交互的应用程序。服务请求者角色可以由浏览器来担当,由人或无用户界面的程序(例如,另外一个 Web 服务)来控制它。 ??? * 服务注册中心。这是可搜索的服务描述注册中心,服务提供者在此发布他们的服务描述。在静态绑定开发或动态绑定执行期间,服务请求者查找服务并获得服务的绑定信息(在服务描述中)。对于静态绑定的服务请求者,服务注册中心是体系结构中的可选角色,因为服务提供者可以把描述直接发送给服务请求者。同样,服务请求者可以从服务注册中心以外的其它来源得到服务描述,例如本地文件、FTP 站点、Web 站点、广告和服务发现(Advertisement and Discovery of Services,ADS)或发现 Web 服务(Discovery of Web Services,DISCO)。 1.2??? WebService用途????????? 异构平台或分布式平台远程调用
?
2?????? WebService实例2.1??? Axis包介绍Axis是一个实现WebService的Framework,Apache Web Services Project(http://ws.apache.org )的一个子项目 2.1.1?? Axis1.4(Axis中最后Release版本)2.1.1.1???????????? 基本概念????????? Axis部署方式有两种: 1,axis最方便的发布WebServices的方法是把你的.java改成.jws的放到Web发布文件夹下的根目录下,此方法叫即时部署 注意:在你写的类中不能有具体包的信息,因为这正是Axis即时部署不支持的
?
?????? 2,通过WSDD自定义部署 2.1.1.2???????????? Axis自带web分析????????? 下载axis1.4 ????????? 启动tomcat
????????? 拷贝webapps/axis到tomcat/ webapps中,tomcat自动部署web module ????????? 访问: http://localhost:8080/axis/,一般可以正常访问到Apache-AXIS主页,并可以点击list察看已发布的web service
?
?
????????? 重点: 1,webservice只需要在一个web container中配置即可? 2,axis自带web.xml中的配置:
?
一个servlet监听器:
三个servlet,其中红色是主控程序
?
servlet的映射地址:
?
?
3,axis自带的webservice在哪配的? ?可能是写到 org.apache.axis.transport.http.AxisServlet 中的 2.1.1.3???????????? 编写自己的webservice下面是如何自己编写并发布一个web service的过程: 服务器测试环境:
?
?
2.1.1.3.1?????? 编写并部署服务器的webservice1,新建一个类,如图: 其中有三个方法,两个简单方法和一个返回类型为自定义类的方法. 写方法 test3的原因主要是要研究webservice如何传递自定义类以及如何在异构平台上传递和接收自定义类.
?
package com.bell.ws;
?
public class Class1 { ??? public Class1() { ??? } ??? public String test1(String p1){ ??????? return "test1:"+p1; ??? } ??? public void test2(){ ??????? System.out.println("i'm test2"); ??? } ??? public MyVO test3(MyVO myvo){ ??????? return myvo; ??? } }
?
?
?
2,在WEB-INF目录下加入一个server-config.wsdd。这是WebServices的发布描述文件,作用类似于web.xml。它有自己的格式 其内容如下: <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> ?<service name="Class1" provider="java:RPC"> ? <parameter name="allowedMethods" value="*"/> ? <parameter name="className" value="com.bell.ws.Class1"/> ?</service> </deployment>
?
重启tomcat后,就可以看到刚刚发布的service了:
但这时点进wsdl时会出错:原因: server-config.wsdd中未加全内容 把内容加全后,测试成功: <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" ??? xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" ??? xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler" ??? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ??? name="defaultClientConfig" xsi:type="deployment"> ??? <globalConfiguration name="defaultClientConfig"> ??????? <parameter name="disablePrettyXML" value="true"/> ??????? <parameter name="dotNetSoapEncFix" value="true"/> ??????? <requestFlow name="RequestFlow1" type=""> ??????????? <handler name="Handler1" type="java:org.apache.axis.handlers.JWSHandler"> ??????????????? <parameter name="scope" value="session"/> ??????????? </handler> ??????????? <handler name="Handler2" type="java:org.apache.axis.handlers.JWSHandler"> ??????????????? <parameter name="scope" value="request"/> ??????????????? <parameter name="extension" value=".jwr"/> ??????????? </handler> ??????? </requestFlow> ??? </globalConfiguration> ??? <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/> ??? <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/> ??? <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/> ??? <transport name="http" type=""> ??????? <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/> ??????? <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/> ??????? <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/> ??????? <requestFlow name="RequestFlow1" type=""> ??????????? <handler name="Handler1" type="URLMapper"/> ??????????? <handler name="Handler2" type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/> ??????? </requestFlow> ??? </transport> ??? <transport name="local" type=""> ??????? <responseFlow name="ResponseFlow1" type=""> ??????????? <handler name="Handler1" type="LocalResponder"/> ??????? </responseFlow> ??? </transport> ??? ??? ?<service name="Class1" provider="java:RPC"> ? <parameter name="allowedMethods" value="*"/> ? <parameter name="className" value="com.bell.ws.Class1"/> ?</service> </deployment>
?
成功页面
?
?
2.1.1.3.2?????? 编写客户端程序调用远程webservice????????? 在上面webservice发布成功的前提下,编写客户端程序进行远程调用:
?
<%@ page import="org.apache.axis.client.Call,org.apache.axis.client.Service,org.apache.axis.encoding.XMLType,org.apache.axis.utils.Options" %> <%@ page import="javax.xml.namespace.QName,javax.xml.rpc.ParameterMode" %> <% ??????? try { ??????????? Service? service = new Service(); ??????????? Call??? call??? = (Call) service.createCall(); ??????????? call.setTargetEndpointAddress( new java.net.URL("http://localhost:8080/axis/services/Class1") ); ??????????? call.setOperationName( new QName("http://ws.mstar.org","test1") ); ??????????? call.addParameter( "arg1",XMLType.XSD_STRING,ParameterMode.IN); ??????????? call.setReturnType( org.apache.axis.encoding.XMLType.XSD_STRING );
?
??????????? String ret = (String) call.invoke( new Object[] { "first test!" } ); ??????????? System.out.println("You typed : " + ret); ??????????? out.println("ret"+ret); ??????? } catch (Exception e) { ?????????? // e.printStackTrace(); ??????????? System.err.println(e.toString()); ??????? } %>
?
?
正常调用的结果页面如下:
?
2.1.1.3.3?????? 编写返回复合类型的webservice上面我们返回的只是简单的string型字串,下面举例说明如何返回复合类型的webservice: 还是使用上面的Class1.java,其中方法test3是返回的MyVO类型: 对server-config.wsdd进行配置:
?
目前会出现: java.io.IOException: No serializer found for class com.bell.ws.MyVO in registry org.apache.axis.encoding.TypeMappingDelegate@38fb59 2.1.2?? Axis2
?
2.2??? Jbuilder2006实现WebService
?
2.3??? 疑问1,安全问题 2,有状态会话问题等等 3,如何跨平台返回复杂类型 4,即然java源文件+wsdd文件即可部署web service,jbuilder中生成的一堆文件是干嘛用的? 3?????? WebService开发经验(网上摘抄)摘自网址:http://www.javaeye.com/topic/73047 去年,在一个大型项目(1500w)中用到Web Services,现在项目进入了尾声,所以对以前的开发经历做一个总结。 如果有以上需求,我想大家应该都比较认同这种异构分布式解决方案:客户端用C# .Net开发,通过Web Services调用服务器端Java组件。 其实,上面的解决方案太过于理想,最后我们不得不面对残酷的现实:三种客户端中的两种最后被迫改为B/S。 以下是我们开发中遇到的实际问题,虽然最终都一一解决,但遇到了几个无法突破的瓶颈:客户端不稳定,客户端响应迟缓,后期测试和维护困难巨大。 一、异构平台的Web Services兼容性 由于Axis是一个嵌入式引擎,所以可以将其打包到最终的WebSphere AppServer(WAS)上,也就是说,我们没有用到WAS提供的Web Services引擎,这引出了后面会谈到的一个问题:Web Services安全性怎么部署? 用Axis时,Axis一直都有一个bug或是说缺陷,官方文档也详细注明,只是我们当时没有发现而走了很多弯路:用Axis发布的Web Services给.net客户端调用时,必须用RPC风格,不能用Web Services标准的跨平台风格Document,而后者是Lomboz axis插件的默认方式。也就是说,我们发布的Web Services总是莫名其妙的不好用。我们用JBuilder2007自带的Axis插件发布,竟然非常顺利。 二、Web Services开发中服务器端组件问题 另外一个问题是,我们的service方法,如果直接给WebWork这样的框架在服务端用的的话,是不会出问题,当提供给.net客户端用时,就会出现lazy loading的错误,因为.net客户端不能接收Proxy对象,必须将数据全部load出来,但这时Hibernate的session已经关闭。项目组很多人遇到这些问题,最后大家不约而同的全部用eager模式,导致了最后的恶果:严重的的性能问题。由于我不是leader,所以当时这个问题发现了,也没法要求别人,毕竟很大的一个团队。 当然,性能问题不只是由Hibernate引起,Web Services本身的性能也非常严重:XML的序列化和反序列化耗时,XML文件的膨胀导致的网络传输,HTTP的无状态导致网络IO性能。切身体会:如果系统必须用分布式,而不是追求所谓的SOA架构,Web Services应该是下下策,因为还有很多协议和方式可以选择:IIOP、RMI、Hessian、burlap、RPC,另外,做系统集成还有Message方式。 Web Services开发中其它问题比较少,因为Web Services本身不用编程,只是部署的事情,开发工具和服务器会自动为我们做,我们只需要理解SOAP引擎的原理和使用就够了,真的遇到问题,可以通过Axis的TcpMonitor监视SOAP数据包。 三、Web Services的安全问题 最后这些问题基本上都解决了,不过还是没有用上,因为在我们已经开发的几种客户端和服务器端部署上很麻烦,还要测试,另外,客户也没法验收这个啊。 当然,我们还回避了一个严肃的问题:我们的Web Services是发布在Axis引擎上,还没有移植到WAS的Web Services引擎,而发布在这个平台,必须有RAD这类开发工具支持,几乎没法手动做。WAS引擎的Web Services安全配置异常复杂:我们当时只配置了Authentication和Integration,没有做Encryption,但完全够用。我当时用Sun的NetBean开发工具发布了一下Web Serivces,也是挺好用的,不过没有配置安全。顺便说一下,Sun的web Services引擎jwsdp2.0设计有点类似于EJB容器,很不好用,移植性特差。 WAS的Web Services安全配置,对照IBM的红皮书,不是很难,但很复杂,安全相关的xml代码都好几百行,好几个文件。配置过程中,和.net客户端通讯时遇到一个问题,怎么也不能互通,但.net和.net客户端可以互通,Java和Java客户端也可以互通,最后我通过拦截soap包,找到了解决办法: 必须手动更改http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3 后的v3,IBM工具生成的是v1,这是标准不兼容引起的,因为当时RAD是04年底,而微软的WSE3.0比较新。后来发现这篇文章有相似的经历:http://pluralsight.com/blogs/kirillg/archive/2005/04/13/7315.aspx 在处理Web Services安全过程中,我通过emule和IBM网站下载了上10本这方面的书籍,我觉得以下资料对我帮助最大: Axis的若干文档:Reference、developers-guide、architecture-guide等,非常详细 四、开发过程中的的沟通问题 从技术的角度表达就是:客户端开发人员需要的接口,服务器端开发人员不清楚;服务器端开发人员也不知道怎么把握粒度。譬如,有个updateUser方法,但更新用户信息时,可能需要更新很多信息:用户信息、用户角色、用户所属组….。loadUser时也有同样的按需加载问题。 当然,从技术角度,开发Web Serivces有Bottom-up和Top-down两种开发模式。我们选择了前者,也是最常见的方式,也许用后者更适合我们的项目:从定义的wsdl文件开始,客户端和服务器端开发都遵循它。但问题是:我们怎么确定wsdl,也就是我们所要求的接口,因为我们自己对业务都不是很熟。 五、客户端和服务端开发测试方法 但问题是: 服务器组件测试一次,起容器特慢,而且客户端调用也慢。 我自己认为的解决方案,但未必真的好用: 六、其它问题 特别提的一点是,我们几乎开发了两套“业务层+持久化”解决方案,因为离线客户端也用了NHibernate持久化,这样导致开发测试工作量巨大,就说一点吧:两边同步是通过打包的sql语句,通过SOAP传输,但Access和DB2的sql有不兼容问题,如果要兼容,就会以牺牲性能和灵活性为代价。 另外,我们写项目建议书时很被动,但也没办法,因为有好几家公司竞争。对我们影响极大的几个问题: 1、IBM的WAS比起WebLogic Server易用性差远了,导致部署时极其耗时。而且还有一些bug,譬如连接池资源,当时不得不和IBM工程师咨询。实际上,我们只用到强大的WAS的一个非常小的部分:Web容器。 当然,这个子系统只是我们那个庞大系统的一个部分。上面也就算我做的一点点总结吧,也是教训啊!不过,从个人角度考虑,学到的东西还是很多的。 这个子系统花去了我们将近200个人月,如果说那浪费的部分,估计至少是100个人月的工作量。是什么导致?从我这篇文章只能窥其一角,因为整个系统涉及CMS、OA、BI、E-commerce、GIS、IM、MIS。我自己总结一下,有以下原因: 不过,说实话,项目团队,特别是进公司一、两年的员工都很努力,没有人抱怨什么,我和他(她)们一起合作,还是很开心的。
?
4?????? 参考资料或网站:
?
WebService学习,开发总结 http://www.mohappy.com/blog/user1/261/archives/2006/2095.html
?
Axis初学手册 http://www.blogjava.net/mstar/archive/2005/10/06/14870.aspx ?(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |