WebService学习笔记1.txt
2007年04月30日 星期一 08:59
对于跨系统的数据交换非常有优势
注意:WebService是一个协议,相当于http协议。
Axis 客户端编程,相当于IE编程。
Axis 服务器编程,相当Web应用服务器编程。
注意这3个方面是在写程序的角度有很大的独立性。
学习阶段:
4。关于WebService.
web service 是一个规范、标准。这个标准需要具体的实现。就象J2EE规范需要有支持这个规范的服务器才能被我们使用一样。
webservice的实现目前主要有:
1。sun的JWSDP-Java Web服务开发人员包(Java Web Services Developer Pack,JWSDP)是一个工具和库的集合
2。AXIS APACHE开源项目的一个子项目。
3。XFire 也是个开源项目。
· SOAP:远程调用。
· UDDI:贸易、目录服务。
· WSDL:描述Web服务特征。
一个WSDL文档在定义网络服务时遵循以下几个原理:
· 类型:使用某种类型的系统进行数据类型定义的容器(如XSD)
· 消息:一种抽象的、被定义类型的通信数据
· 操作:由服务所支持的一个抽象描述的动作
· 端口类型:由一个或多个端点支持的一个操作的抽象集合
· 绑定:针对一个特定端口类型的具体的协议和数据格式规范
· 端口:被定义成一个结合绑定和网络地址的一个单一的端点
· 服务:相关端点的集合
由此可见,WSDL为客户提供了一个服务描述的模板。
SOAP是一个协议规范,定义了传递XML-encoded数据时的统一方式;同时它也定义了使用HTTP作为底层通信协议时,执行远程调用(RFC)的方法。
UDDI为客户提供了一种动态查找其它Web服务的机制。可以将它看作商业应用程序的DNS服务。
?WebService如何实现身份验证?在每个请求的时候都把用户名和密码
同时使用Web服务的身份验证和授权技术,提高系统的安全性。由于Web Service在安全性方面的标准刚刚出台,还没有实际应用,所以系统在身份认证和授权技术方面的实现还比较简单,只提供简单的密码和授权认证。
用hanlder是否可以?
关于Axis1.4
可以在浏览器地址栏中输入地址得到相关的soap原代码、调用webservice服务。
例如:http://loalhost/axis/HelloService.jws?method=sayHello¶meter=ipaddr
这是在sayHello函数只有一个参数的情况下可以使用的。
在Tomcat服务器中,java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd到底做了什么:
只是把deploy.wsdd的service里的内容放到server_config.wsdd里
答:org.apache.axis.client.AdminClient的作用分2步:
1步,是把deploy.wsdd里的service标记放到server_config.wsdd里。
注意:这一步是我们手工也可以做的。
2步,更新内存里的server_config.wsdd为最新的。
这步是手工不能做的。
如果
第一步,手动加入service标记到server_config.wsdd中,
第二步,那么重起Tomcat让服务器从新读一次server_config.wsdd。
与org.apache.axis.client.AdminClient执行的效果是一样的。
EndPoint地址:
客户端访问的时候设置的call.setTargetEndpointAddress("http://localhost:8080/axis/Distance.jws");与.wsdl文件里这部分对应:
- <wsdl:service name="DistanceService">
- <wsdl:port binding="impl:DistanceSoapBinding" name="Distance">
<wsdlsoap:address location="http://127.0.0.1:8080/axis/Distance.jws" />
</wsdl:port>
</wsdl:service>
Axis支持三种web service的部署和开发,分别为:
1、Dynamic Invocation Interface ( DII) (.jws放到Web的跟目录下,直接用Service 和Call类调用)
2、Stubs方式
(.java放到java的包里,然后修改server-config.wsdd就行了。
至于Handler和client stub(生成测试文件)都是可选的。
)
3、Dynamic Proxy方式 (.jws放到Web的跟目录下, 在写个接口,在客户端用ServiceFactory、Service和哪个接口接口调用)
Axis支持三种web service的部署到底有几种:为什么Stubs方式 和其他文章的制定发布方式不同。
这篇文章中,Stubs方式的Handler和client stub部分是多余的。不是ws必须的。所以与其他文章中制定发布是一样的
在Stub的部署方式中,client stub的作用:测试吗
答: client stub是由Axis提供的。
client stub是指:如下一个命令
执行下面的命令生存client stub
java org.apache.Axis.wsdl.WSDL2Java -p client http://localhost:8080/Axis/services/SayHello.jws?wsdl
执行如下命令生成SayHello.wsdl
java org.apache.Axis.wsdl.Java2WSDL -oSayHello.wsdl -l http://localhost:8080/Axis/services/SayHello -nsayhello server.SayHello
执行如下命令生成client stub
java org.apache.Axis.wsdl.WSDL2Java SayHello.wsdl -p client
生成的stub client文件列表为:
1.SayHello.java
2.SayHelloService.java。
3.SayHelloServiceLocator.java
4.SayHelloSoapBindingStub.java
这些文件封装了ServiceFactory、Service 和Call等类。可以用这些文件里的类调用WS比较方便。
可以用到测试里,直接用他们变成也挺好。但这些都是client部分的东西,与ws服务本身无关,不影响ws的正常运行。
WS可以使用自定义类型,这样使用client stub就很方便了。
\Tomcat 5.0\webapps\axis\WEB-INF里保存了.jws生成的.class文件。
关于WTP
Tomcat下的Axis没有生成wsdl文件,WTP为什么要生成吗。有用吗。如果删除会不回影响ws的运行。
答:会影响部署,但不影响运行。如果保留文件,但把.wsdl文件的内容全删了并不影响WS运行,发布也能成功。
.wsdl,AXIS和WSDD(.wsdd文件和server-config.wsdd),.java(.class)的关系。
.wsdl,是WebService的类型定义,
就象.java文件中定义类的类型和相关信息一样。
soap请求一个wsdl所定义的WebService(或称功能)。Axis根据server-config.wsdd文件里的信息把.java文件与之.wsdl关联。
?WebService能否实现类似目前我们所使用的3层框价的框架?有什么优势和劣势。
总结java后的参数。-classpath、-cp、-D java.ext.dirs
Axis1与Axis2的区别。
见文章:在网站http://www.opentown.info/,Understanding Axis2 Deployment Architecture ——理解Axis2部署体系
soap client工具是什么
答:soap是一个协议,就象html,但html有ie等浏览器,使用soap的时候,编程的时候没有这些soap浏览器,就需要工具生成一些重复的代码。
如何向WTP那样保留.wsdl文件
执行下面的命令生存client stub
java org.apache.Axis.wsdl.WSDL2Java -p client http://localhost:8080/Axis/services/SayHello.jws?wsdl
还有一个类org.apache.axis.wsdl.Java2WSDL,也许也可以。
WTP开发的Tomcat运行的WebService,也可以想Tomcat中手工写的文件那样在IE的地址栏请求,并获得结果吗
完全可以用类似http://127.0.0.1:8080/ws/services/Pdd?method=getStr¶meter=SoEasy的方式请求并得到如下结果。
<?xml version="1.0" encoding="UTF-8" ?>
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <getStrResponse xmlns="">
<ns1:getStrReturn xmlns:ns1="http://ws.forecast.cn">Hello: SoEasy</ns1:getStrReturn>
</getStrResponse>
</soapenv:Body>
</soapenv:Envelope>
但是与Tomcat中手工写的文件不同的是.wsdl必须存在。如果不存在就pulish不成功。导致WebService运行不起来。
这个问题是部署的问题。
如果把.wsdl里的文件内容全都删除但保留这个文件。通过地址栏就可以访问了Webservice了。
通过WebService?wsdl也可以看到完整的.wsld文件。可见。哪个文件在通过地址栏访问的时候是没有用的。
WTP还有一个客户端项目,这个项目是用client stub相关工具生成的。是个测试项目不产生他也一样运行WebService。
包org.apache.Axis和org.apache.axis在版本上的区别:
大写的Axis可能是作者笔误,或者是老版本。
到apache官方网站上,各种版本全是打包的下载太麻烦。
再说没有什么意义。不再查了
现在感觉WTP在发布ws的时候,很麻烦,也是这是为了适应,更复杂的设计,毕竟现在所做的例子都是非常简单的。
比如,也许可以自动根据xml生成对象等。——可以的。
在客户端和服务端都是java的时候是可以把一些对象作为WS的输入和输出。通过ClientStub的方式直接得到对象。
但在传输的时候xml,具体是什么格式的。知道了具体的格式,也就可以让C等其他语言进行解析了。
支持返回值是Bean的ws。调用一下就能看到格式了。
http://www.eclipse.org/webtools/initial-contribution/IBM/evalGuides/WebServicesToolsEval.html?p=1上的
Web Services Tools Evaluation Guide
Extensible Wizards for creating Web service clients from WSDL.
这句话解释了,为什么要生成.wsdl文件
Included in the contribution are tools for building Apache Axis Web services and Web service clients on Apache Tomcat.
测试程序最好运行在Apache Tomcat. 上。
Using the Web Services Explorer to test a Web service
通过eclipse内置浏览器的地址得到了.http://localhost:0/wsexplorer/wsexplorer.jsp?org.eclipse.wst.ws.explorer=4这个连接
在eclipse文件夹里搜索wsexplorer找到一个wsexplorer.war包放到Tomcat/webapps/中,访问上边的地址得到错误.提示类没有找到
估计是有些.jar没有考过来.
又把wsexplorer文件夹考过来,也抛出异常,放弃。
没有测试成功.
写完java类的发布成WebService基本也没有
部署的时候的错误。
IWAB0398E Error in generating WSDL from Java java.lang.NoClassDefFoundError
把HMW他们项目的.jar包考过来也没有解决问题
部署没有成功。
WTP是个大垃圾,BUG太多了。
?上次只搜索错误了.应该搜索一下中文的完整的WTP发布WS的过程,我看的是官方文档,实际可能还有别的方法。不搜错误,搜方法。
放弃WTP作为开发工具。直接用eclispe+myeclipse+weblogic+手工配置。
Axis在weblogic上的应用。
- Unable to find config file. Creating new servlet engine config file: /WEB-INF/server-config.wsdd
但无论在weblogic还是eclipse的workspace中都没有找到这个文件。
准备:把\axis-src-1_4\axis-1_4\webapps\axis\WEB-INF\lib考到\WebRoot\WEB-INF\lib中,添加构件路径。这些.jar才是必须的。
1。制定发布:
1。1。在运行java org.apache.axis.client.AdminClient deploy.wsdd的时候把他放在eclipse的workspace\WSServer\WebRoot\WEB-INF\classes\sls>,
执行发生异常,没有成功。
异常如下
E:\workspace\eclipse\WSServer\WebRoot\WEB-INF\classes\sls>java org.apache.axis.client.AdminClient deploy.wsdd
Processing file deploy.wsdd
Exception: AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.net.ConnectException: Connection refused: connect
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.axis.components.net.DefaultSocketFactory.create(DefaultSocketFactory.java:153)
at org.apache.axis.components.net.DefaultSocketFactory.create(DefaultSocketFactory.java:120)
at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:1792)
at org.apache.axis.client.AdminClient.process(AdminClient.java:439)
at org.apache.axis.client.AdminClient.process(AdminClient.java:404)
at org.apache.axis.client.AdminClient.process(AdminClient.java:410)
at org.apache.axis.client.AdminClient.process(AdminClient.java:320)
at org.apache.axis.client.AdminClient.main(AdminClient.java:463)
{http://xml.apache.org/axis/}hostname:kangxiaoguang
在weblogic目录下执行抛出同样的异常。
1。2。
首先获得server-config.wsdd,使用文章:AxisDevelopGuide.doc用Axis开发基于Java的Web服务,中的java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd命令。deploy内容如下:
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="Capacity" provider="java:RPC">
<parameter name="className" value="samples.capacity.Capacity"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
用饶过这个命令的方式直接编写server-config.wsdd,然后从新启动。由于虽然控制台中提示建立了server-config.wsdd,但在文件系统中(无论Tomcat还时候Weblogic)找不到server-config.wsdd。所以要手工生成。
测试成功,更改.java类的时候不需要重新启动服务器,在改动server-config.wsdd要让他生效,需要重新启动。
有时可能发生下边这个异常,但对程序没有影响。一般产生在编辑文件后的第一次请求WS
<2006-5-12 下午10时19分52秒 CST> <Error> <HTTP> <BEA-101309> <[ServletContext(id=32433147,name=WSServer,context-path=/WSServer)] could not deserialize the context attribute "AxisEngine"
java.io.NotSerializableException: org.apache.axis.configuration.FileProvider
当返回值是的bean的时候,?wsdl多了<wsdl:types>标记,定义这种自定义类型,
此时调用WS,对应的函数已经执行了。但返回值是异常,因为Axis不知道如何序列化这个类。
在server-config.wsdd 中加入<beanMapping qname="ns:loca" classname="sls.WsBean"></beanMapping>标记,让Axis知道如何序列化这个类。
结果还是不成功,连函数都不执行了。?wsdl报服务器内部错误,但在控制台中没有显示。
直接调用WS得到soapenv:Server.userException java.lang.NullPointerException kangxiaoguang 错误。
在server-config.wsdd 中加入的beanMapping标记改成如下:
<beanMapping languageSpecificType="java:sls.WsBean" qname="ns1:WsBean"
xmlns:ns1="urn:BeanService"/>
并且是加在service标记中。
languageSpecificType属性指定JavaBean类文件位置,例如:
languageSpecificType="java:com.ronghao.axis.Order"
qname属性指定JavaBean类的名字
其他是固定的。
完整的标记是:
<service name="Fws" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="className" value="sls.Fws"/>
<beanMapping languageSpecificType="java:sls.WsBean" qname="ns1:WsBean"
xmlns:ns1="urn:BeanService"/>
</service>
测试成功
返回结果:
<?xml version="1.0" encoding="UTF-8" ?>
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <helloWSResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<helloWSReturn href="#id0" />
</helloWSResponse>
- <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns1:WsBean" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:BeanService">
<ib xsi:type="xsd:int">121</ib>
<sb xsi:type="xsd:string">SoGood</sb>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
以下是这个返回值的java代码。
public class WsBean implements Serializable
{
private String sb;
private int ib;
public int getIb()
{
return ib;
}
public void setIb(int ib)
{
this.ib = ib;
}
public String getSb()
{
return sb;
}
public void setSb(String sb)
{
this.sb = sb;
}
}
理想的结果是WS对复杂的bean能返回一个根据属性名成声的xml文件。
这个返回值的格式,要复杂些但与自己想要的基本相同。
注意,返回的bean的属性中完全可以使用List接口作为Bean的属性。实际赋的对象是ArrayList类型的。
并且,ArrayList中的元素,也可以是个Bean。Axis可以清晰的把这些解析成xml返回给IE,或其他soap客户端。
但要是用List,Map作为WS的参数,可能就会有问题。
在IE地址栏中有get方式访问WS,有多个参数的时候可以写成,
http://localhost:7001/WSServer/services/Fws?method=helloWS&方法中的参数名1=SoGood&方法中的参数名2=fdfes。
这样能把值准确的赋到对应的变量上,也可以用parameter1、parameter2等代替参数名,但是同过什么顺序赋值的,还没有搞清楚。