??xml version="1.0" encoding="utf-8" standalone="yes"?>
No matter which approach you take, make sure not to include jar files other than jaxb-api.jar . Doing so, for example including jaxb-xjc.jar , may result in classloading related errors such as "taskdef A class needed by class com.sun.tools.xjc.XJCTask cannot be found: org/apache/tools/ant/...."
See the endorsed directory mechanism for more details.
下面是配|和使用soapmonitor模块的步骤:
W?/span>1步:部vApplet?/span>Servlet
׃axis2默认情况下已l自带了soapmonitor模块Q因此,soapmonitor模块q不需要单独安装。但applet所涉及到的相应?/span>.class文g需要安装一下。在<Tomcat安装目录>\webapps\axis2\WEB-INF\lib目录中找?/span>soapmonitor-1.4.1.jar文gQ将该文件解压。虽?/span>appletq不需?/span>soapmonitor-1.4.1.jar文g中所有的.class文gQ但Z方便Q读者也可以直接解压目录中?/span>org目录复制?/span><Tomcat安装目录>\webapps\axis2目录中,Applet所需?/span>.class文g需要放在这个目录。然后再?/span>org目录复制?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\classes目录中,soapmonitor模块中的Servlet所对应?/span>.class文g需要放在这个目录?br />
W?/span>2步:配置Servlet
打开<Tomcat安装目录>\webapps\axis2\WEB-INF\web.xml文gQ在其中加入如下的内容:
W?/span>3步:?/span>services.xml文g中引?/span>soapmonitor模块
与引用logging模块一P引用soapmonitor模块也需要?lt;module>元素Q引用soapmonitor模块的services.xml文g的内容如下: ׃soapmonitor模块已经?/span>axis2.xmlq行配置了,因此Q在本例中不需要再?/span>axis2.xml文gq行配置了?nbsp;
W?/span>4步:使用soapmonitor模块
启动Tomcat后,在浏览器中输入如下的URLQ?br /> 在浏览器中将出现soapmonitor所带的Applet的界面,当访?/span>MyService?/span>getGreetingҎӞ?/span>Tomcat控制CApplet中都昄了相应的SOAPh和响应消息。如?/span>1和图2分别是调用了两次getGreetingҎ后输出的SOAPh和响应消息?br />
如果读者想?/span>logging?/span>soapmonitor模块监视部v?/span>Axis2中的所?/span>WebServiceQ可以在axis2.xml文g中?/span><module>元素来引用这两个模块Q代码如下:
?
?
<module ref="logging"/>
<!-- 引用soapmonitor模块 -->
<module ref="soapmonitor"/>
]]>
1. ~写实现Module接口的类?/span>Axis2模块在进行初始化、销毁等动作时会调用该类中相应的ҎQ?/span>
2. ~写实现Handler接口的类。该cLAxis2模块的业务处理类?/span>
3. ~写module.xml文g。该文g攑֜META-INF目录中,用于配置Axis2模块?/span>
4. ?/span>axis2.xml文g中配|?/span>Axis2模块?/span>
5. ?/span>services.xml文g中配|?/span>Axis2模块。每一?/span>Axis2模块都需要?/span><module>元素引用才能使用?/span>
6. 发布Axis2模块。需要?/span>jar命o?/span>Axis2模块压羃?/span>.mar包(文g扩展名必L.marQ,然后?/span>.mar文g攑֜
<Tomcat安装目录>\webapps\axis2\WEB-INF\modules目录中?nbsp;
先来~写一个WebServicec,代码如下Q?br />
下面我们来编写一个记录请求和响应SOAP消息?/span>Axis2模块。当客户端调?/span>WebServiceҎӞ?/span>Axis2模块会将h和响?/span>SOAP消息输出?/span>Tomcat控制C?/span>
W?/span>1步:~写LoggingModulec?/span>
LoggingModulecdCModule接口Q代码如下:
在本例中LoggingModulecdƈ没实现实际的功能Q但该类必须存在。当Tomcat启动时会装蝲?/span>Axis2模块Q同时会调用LoggingModulecȝinitҎQƈ?/span>Tomcat控制C输出“init”?/span>
W?/span>2步:~写LogHandlerc?br />
LogHandlercdCHandler接口Q代码如下:
LogHandlercȝ核心Ҏ?/span>invokeQ当使用?/span>Axis2模块?/span>WebService的方法被调用ӞLogHandlercȝinvokeҎ被调用?nbsp;
W?/span>3步:~写module.xml文g
W?/span>4步:?/span>axis2.xml文g中配|?/span>Axis2模块
打开axis2.xml文gQ分别在如下四个<phaseOrder>元素中加?/span><phase name="loggingPhase"/>Q?br />
W?/span>5步:?/span>services.xml文g中引?/span>logging模块
services.xml文g的内容如下:
W?/span>6步:发布logging模块
到现在ؓ止,我们应用可以建立两个发行包:logging.mar?/span>service.aar。其?/span>logging.mar文g?/span>Axis2模块的发行包Q该包的目录l构如下Q?/span>
logging.mar
module\LoggingModule.class
module\LogHandler.class
META-INF\module.xml
service.aar文g是本例编写的WebService发行包,该包的目录结构如下:
service.aar
service\MyService.class
META-INF\services.xml
?/span>logging.mar文g攑֜<Tomcat安装目录>\webapps\axis2\WEB-INF\modules目录中,?/span>service.aar文g攑֜<Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中。要注意的是Q如?/span>modules目录中包含了modules.list文gQ?/span>Axis2会只装蝲在该文g中引用的Axis2模块Q因此,必须在该文g中引?/span>logging模块Q该文g的内容如下:
addressing-1.4.1.mar
soapmonitor-1.4.1.mar
ping-1.4.1.mar
mex-1.4.1.mar
axis2-scripting-1.4.1.mar
logging.mar
如果modules目录中不包含modules.list文gQ则Axis2会装?/span>modules文g中的所?/span>Axis2模块?/span>
现在启动TomcatQ用如下的C#代码调用MyService?/span>getGreetingҎ则会?/span>Tomcat控制C输出相应的请求和响应SOAP消息?br />
在执行上面的代码后,?/span>Tomcat控制C输出的信息如?/span>图所C?br />
转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/02/16/254826.html
Z模拟需要一定时间才q回?/span>WebServiceҎQ在getNameҎ中用了sleepҎ来gq?/span>5U?/span>
下面?/span>MyServicecȝ配置代码Q?br />
从上面的配置代码可以看出Q?/span>MyService的配|方式与前几章的WebService的配|方式完全一P也就是说Q?/span>MyService只是一个普通的WebService?/span>
下面是异步调?/span>MyService?/span>Java客户端代码:
从上面的代码可以看出Q?/span>invokeNonBlockingҎ有三个参敎ͼ前两个参数分别指定了要调用的Ҏ及方法参数的相关信息Q而最后一个参数ƈ不是Ҏq回值的cd信息Q而是一个实?/span>org.apache.axis2.client.async.AxisCallback接口的类的对象实例。在本例中隐式实CAxisCallback接口。在AxisCallback接口中有四个Ҏ需要实玎ͼ其中当被异步调用的方法返回时onMessageҎ被调用。当q行上面的程序后Q将输出如下的信息:
虽然上面的例子可以实现异步调用,但比较麻烦。ؓ了更方便地实现异步调用,可以使用wsdl2java命o?/span>-a参数生成可异步调用的StubcR下面的命o可生成同步和异步调用的客L代码Q两个类Q,其中-s表示生成同步调用代码Q?/span>-a表示生成异步调用代码?/span>
在执行上面的命o后,生成两个类Q?/span>MyServiceStub?/span>MyServiceCallbackHandlerc,其中MyServiceStubc负责同步和异步调用WebServiceQ?/span>MyServiceCallbackHandlercL一个抽象类Q也是一个回调类Q当使用异步方式调用WebServiceҎӞ如果Ҏq回Q则MyServiceCallbackHandlercȝreceiveResultgetNameҎ被调用。下面是使用MyServiceStubcd步访?/span>WebService的代码:
执行上面的程序后Q将输出如下的信息:
其中async是引?/span>MyService的服务名。要注意的是Q在C#中不能在同一?/span>WebService实例?/span>getNameҎ未返回之前,再次调用该实例的getNameҎQ否则将抛出异常。如下面的代码会抛出一个异常:
但不同的WebService实例的方法可以在Ҏ未返回时调用Q如下面的代码是可以正常工作的:
其中Person也是一?/span>JavaBeanQ代码如下:
上面两?/span>Java源文件编译后Q放?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\classes目录中?/span>
?/span><Tomcat安装目录>\webapps\axis2\WEB-INF目录中徏立一?/span>applicationContext.xml文gQ该文g?/span>Spring框架用于装配JavaBean的配|文Ӟ内容如下Q?br />
?/span>applicationContext.xml文g中装配了service.SpringServicec,q被始化?/span>name?/span>job属性。在配置?/span>SpringServicecdQ就可以直接在程序中FileSystemXmlApplicationContextcL其他cM功能的类dapplicationContext.xml文g中的内容Qƈ获得SpringServicecȝ对象实例。但现在我们q不q样做,而是?/span>SpringServicecd布成WebService?/span>
?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\lib目录中有一?/span>axis2-spring-1.4.1.jar文gQ该文g用于被装配JavaBean的发布成WebService。在D盘徏立一?/span>axi2-spring-ws目录Qƈ在该目录中徏立一?/span>META-INF子目录。在META-INF目录中徏立一?/span>services.xml文gQ内容如下:
?/span>Windows控制台进?/span>axi2-spring-ws目录Qƈ使用jar命o?/span>axi2-spring-ws目录中的内容打包?/span>axi2-spring-ws.aarQ然后将该文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中,启动Tomcat后,可以访问该WebService了,讉K方式与前面几文章的讉K方式相同。获?/span>wsdl内容?/span>URL如下Q?br />
http://localhost:8080/axis2/services/springService?wsdl
在将Spring中的装配JavaBean发布?/span>WebService需要注意以下几点:
1. ?/span>JavaBean~译生成?/span>.class文g需要放?/span>WEB-INF\classes目录中,或打?/span>.jar包后攑֜WEB-INF\lib目录中,?/span>WEB-INF\services目录中的.aar包中不需要包?/span>.class文gQ而只需要包含一?/span>META-INF目录Qƈ在该目录中包含一?/span>services.xml文g卛_?/span>
2. services.xml的配|方法与前几文章的配置ҎcMQ只是ƈ不需要?/span>ServiceClass参数指定要发布成WebService?/span>Javac,而是要指定在applicationContext.xml文g中的装配JavaBean的名UͼSpringBeanName参数Q?/span>
3. ?/span>services.xml文g中需要通过ServiceObjectSupplier参数指定SpringServletContextObjectSuppliercL获得Spring?/span>ApplicationContext对象?br />
转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/02/13/254499.html
实现跨服务的Session理需要如下三步:
1. 使用MessageContext?/span>ServiceGroupContext获得与设|?/span>key-value寏V?/span>
2. q行Session理?/span>WebServicecL对应?/span><service>元素d一?/span>scope属性,q将该属性D?/span>application?/span>
3. 在客L使用setManageSession(true)打开Session理功能?/span>
从上面的步骤可以看出Q实现跨服务会话理与实现同一个服务的会话理在前两步上存在着差异Q而第3步是完全一L。下面是一个跨服务的会话管理的实例。在q个例子中有两个WebServicec:LoginService?/span>SearchServiceQ代码如下:
LoginService.java
SearchService.java
services.xml文g中的配置代码如下Q?br />
W?/span>3步与《WebService大讲堂之Axis2(5)Q会话(SessionQ管理?/a>一文中介绍的方法类伹{?br />
下面是用两?/span>stubcȝ对象实例讉K上面实现的两?/span>WebService的客L代码Q?br />
在执行上面的代码后,输出如下的信息Q?/span>
读者可以将scope属性值改成transportsessionQ看看会输出什么!
实际上,Axis2的会话管理也是通过Cookie实现的,与Web应用中的Session理cM。如果读者用C#讉K支持会话Q在同一个服务中的会话管理)的WebServiceQ需要指定一个CookieContainer对象Q代码如下:
如果是访问跨服务的支持会话的WebServiceQ则不需要指?/span>CookieContainer对象Q代码如下:
如果读者?/span>delphiQ本文用的?/span>delphi2009Q其他的delphi版本误者自行测试)调用支持会话?/span>WebService时有一些差别。经W者测试,使用delphi调用WebServiceQ将scope属性D?/span>transportsession?/span>application都可以实现跨服务的会话管理,q一点和Java?/span>C#不同Q?/span>Java?/span>C#必须?/span>scope属性D?/span>application才支持跨服务会话理。在delphi中不需要象C#指定一?/span>CookieContainer或其他类似的对象Q而只需要象讉K普通的WebService一栯问支持会话的WebService卛_?/span>
读者可以想象,q对于一个完整的应用E序Q无法保留状态,意味着只依?/span>WebService很难完成全部的工作。例如,一个完整的应用pȝ都需要进行登录,q在Web应用中?/span>Session来保存用L录状态,而如果用WebService的方法来q行d处理Q无法保存登录状态是非常令h尬的。当Ӟq也可以通过其他的方法来解决Q如在服务端使用static变量来保存用L态,q发送一?/span>id到客LQ通过在服务端和客L传递这?/span>id来取得相应的用户状态。这非常cM?/span>Web应用中通过Session?/span>Cookie来管理用L态。但q就需要由开发h员做很多工作Q不q幸?/span>Axis2为我们提供了WebService状态管理的功能?/span>
使用Axis2来管?/span>WebService的状态基本上对于开发h员是透明的。在WebServicec需要?/span>org.apache.axis2.context.MessageContext?/span>org.apache.axis2.context.ServiceContextcL保存与获得保存在服务端的状态信息,q有些象使用HttpSession接口?/span>getAttribute?/span>setAttributeҎ获得与设|?/span>Session域属性?/span>
除此之外Q还需要修?/span>services.xml文g的内容,?/span><service>元素加一?/span>scope属性,该属性有四个可取的|Application, SOAPSession, TransportSession, RequestQ不q要注意一下,虽然Axis2的官Ҏ档将q四个值的单词首字母和~写字母都写成了大写Q但l笔者测试,必须全部写才有效,也就是这四个值应为:application?/span>soapsession?/span>transportsession?/span>requestQ其?/span>request?/span>scope属性的默认倹{读者可以选择使用transportsession?/span>application分别实现同一?/span>WebServicecd?/span>WebServicecȝ会话理?/span>
在客L需要?/span>setManageSession(true)打开Session理功能?/span>
lg所qͼ实现同一?/span>WebService?/span>Session理需要如下三步:
1. 使用MessageContext?/span>ServiceContext获得与设|?/span>key-value寏V?/span>
2. q行Session理?/span>WebServicecL对应?/span><service>元素d一?/span>scope属性,q将该属性D?/span>transportsession?/span>
3. 在客L使用setManageSession(true)打开Session理功能?/span>
下面是一个在同一?/span>WebServicecM理Session的例子?/span>
先徏立一个WebServicec,代码如下Q?br />
?/span>LoginServicecM有两个方法:login?/span>getLoginMsgQ如?/span>loginҎd成功Q会?#8220;成功d”字符串保存在ServiceContext对象中。如果在loginҎq回true后调?/span>getLoginMsgҎQ就会返?#8220;成功d”?/span>
下面?/span>LoginServicecȝ配置代码Q?/span>services.xmlQ:
使用如下的命令生成客L使用?/span>stubc:
?/span>stub\src\client目录中生成了一?/span>LoginServiceStub.javac,在该cM扑ֈ如下的构造句ҎQ?br />
在该Ҏ中最后添加如下的代码Q?br />
下面的客L代码使用LoginServiceStub对象讉K了刚才徏立的WebServiceQ?br />
q行上面的代码后Q会输出“成功d”信息?br />
转自Q?a href="http://www.aygfsteel.com/nokiaguy/archive/2009/01/26/252564.html">http://www.aygfsteel.com/nokiaguy/archive/2009/01/26/252564.html
上面代码?/span>services.xml文g的配|代码如下:
如果使用wsdl2java命o生成调用Java客户端代码,则需要创?/span>DataHandlercȝ对象实例Q代码如下:
wsdl2java命o会ؓ每一个方法生成一个封装方法参数的c,cd为方法名Q第一个字W大写)Q如uploadWithByteҎ生成的类名ؓUploadWithByte。如果要讄file参数的|可以使用UploadWithBytecȝsetFileҎQ代码如下:
最后是调用uploadWithByteҎQ代码如下(FileServiceStub?/span>wsdl2java生成?/span>stubcdQ:
如果使用C#调用FileServiceQ则file参数cd均ؓbyte[]Q代码如下:
其中picUpdateImage?/span>c#中加载图像文件的picturebox控g?br />
转自Qhttp://www.aygfsteel.com/nokiaguy/archive/2009/01/archive/2009/01/archive/2009/01/archive/2009/01/22/252305.html
q个cL两个ҎQ这两个Ҏ都需要发布成Web ServiceҎ。这U方式和直接攑֜pojo目录中的POJOcM同。要惛_MyServicecd布成Web ServiceQ需要一?/span>services.xml文gQ这个文仉要放?/span>META-INF目录中,该文件的内容如下Q?/span>
其中<service>元素用于发布Web ServiceQ一?/span><service>元素只能发布一?/span>WebServicec,name属性表C?/span>WebService名,如下面的URL可以获得q个WebService?/span>WSDL内容Q?br />
其中name属性名是上面URL?/span>"?"?/span>"/"之间的部分?/span>
<description>元素表示当前Web Service的描qͼ<parameter>元素用于讄WebService的参敎ͼ在这里用于设|?/span>WebService对应的类名。在q里最值得注意的是<messageReceivers>元素Q该元素用于讄处理WebServiceҎ的处理器。例如,getGreetingҎ有一个返回|因此Q需要用可处理输入输出?/span>RPCMessageReceiverc,?/span>updateҎ没有q回|因此Q需要用只能处理输入的RPCInOnlyMessageReceivercR?/span>
使用q种方式发布WebServiceQ必L包成.aar文gQ?/span>..aar文g实际上就是改变了扩展名的.jar文g。在现在建立了两个文ӞMyService.java?/span>services.xml。将MyService.java~译Q生?/span>MyService.class?/span>services.xml?/span>MyService.class文g的位|如下:
D:\ws\service\MyService.class
D:\ws\META-INF\services.xml
?/span>windows控制Cq入ws目录Qƈ输入如下的命令生?/span>.aar文gQ实际上Q?jar文g也可以发布webserviceQ但axis2官方文档中徏议?aar文g发布webserviceQ:
jar cvf ws.aar .
最后将ws.aar文g复制?/span><Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中,启动Tomcat后,可以调用这?/span>WebService了。调用的Ҏ?/span>《WebService大讲堂之Axis2Q?Q:用POJO实现0配置的WebService?/a>所讲的ҎcM?/span>
另外services.xml文g中也可以直接指定WebServicecȝҎQ如可以用下面的配置代码来发?/span>WebServiceQ?/span>
上面的配|代码前面的部分和以前的services.xml文g的内容相同,但后面用了<operation>元素来指定每一?/span>WebServiceҎQƈ单独指定了处理每一个方法的处理器。对于客L来说Q调用用这两个services.xml文g发布?/span>WebServiceq没有太大我区别Q只是用第二个services.xml文g发布WebServices后,在?/span>wsdl2java命o或?/span>C#?/span>delphi{生成客L?/span>stubӞupdateҎ?/span>Stringcd被封装在?/span>updatecMQ在传?/span>updateҎ的参数时需要徏?/span>updatecȝ对象实例。而用第一?/span>services.xml文g发布?/span>WebService在生?/span>stub时直接可以ؓupdateҎ传?/span>Stringcd的参数。从q一点可以看出,q两U方法生成的WSDL有一定的区别。但实际上,如果客户端程序用第一?/span>services.xml文g发布?/span>WebService生成stubcLQ这?/span>updateҎ的参数是StringQ,在服务端又改为第二个services.xml文g来发?/span>WebServiceQ这时客Lq不需要再重新生成stubc,而可以直接调?/span>updateҎ。也是_服务端用什么样的方式发?/span>WebServiceQ对客户端ƈ没有影响?/span>
如果惛_布多?/span>WebServiceQ可以?/span><serviceGroup>元素Q如再徏立一?/span>MyService1c,代码如下Q?br />
?/span>services.xml文g中可以用如下的配置代码来配|?/span>MyService?/span>MyService1c:
一?/span>Axis2的下载和安装
读者可以从如下的网址下蝲Axis2的最新版本:
在本文用了目前Axis2的最新版?/span>1.4.1。读者可以下载如下两?/span>zip包:
axis2-1.4.1-bin.zip
axis2-1.4.1-war.zip
其中axis2-1.4.1-bin.zip文g中包含了Axis2中所有的jar文g, axis2-1.4.1-war.zip文g用于?/span>WebService发布?/span>Web容器中?/span>
?/span>axis2-1.4.1-war.zip文g解压到相应的目录Q将目录中的axis2.war文g攑ֈ<Tomcat安装目录>\webapps目录中(本文使用?/span>Tomcat的版本是6.xQ,q启?/span>Tomcat?/span>
在浏览器地址栏中输入如下?/span>URLQ?/span>
如果在浏览器中显C出如图1所C的面Q则表示Axis2安装成功?br />
二、编写和发布WebService
对于?/span>Java实现的服务程序给人的印象是需要进行大量的配置Q不q这一点在Axis2中将被终l。在Axis2中不需要进行Q何的配置Q就可以直接一个简单的POJO发布?/span>WebService。其?/span>POJO中所有的publicҎ被发布?/span>WebServiceҎ?/span>
下面我们来实C个简单的POJOQ代码如下:
?/span>SimpleServicecM有两个方法,׃q两个方法都?/span>publicҎQ因此,它们都将作ؓWebServiceҎ被发布?/span>
~译SimpleServicecdQ将SimpleService.class文g攑ֈ<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中(如果没有pojo目录Q则建立该目录)。现在我们已l成功将SimpleServicecd布成?/span>WebService。在览器地址栏中输入如下?/span>URLQ?/span>
http://localhost:8080/axis2/services/listServices
q时当前面显C所有在Axis2中发布的WebServiceQ如?/span>2所C?br />
在浏览器地址栏中输入如下的两?/span>URL来分别测?/span>getGreeting?/span>getPriceҎQ?/span> http://localhost:8080/axis2/services/SimpleService/getGreeting?name=bill http://localhost:8080/axis2/services/SimpleService/getPrice ? getGreetingҎ的测试结?/span>
? getPriceҎ的测试结?/span>
在编写、发布和试0配置?/span>WebService时应注意如下几点Q?/span> 1. POJOcM能?/span>package关键字声明包?/span> 2. Axis2在默认情况下可以热发?/span>WebServiceQ也是_?/span>WebService?/span>.class文g复制?/span>pojo目录中时Q?/span>Tomcat不需要重新启动就可以自动发布WebService。如果想取消Axis2的热发布功能Q可以打开<Tomcat安装目录>\webapps\axis2\WEB-INF\conf\axis2.xmlQ找到如下的配置代码Q?/span> ?/span>true改ؓfalse卛_。要注意的是Q?/span>Axis2在默认情况下虽然是热发布Q但q不是热更新Q也是_一旦成功发布了WebServiceQ再x新该WebServiceQ就必须重启Tomcat。这对于开发h员调?/span>WebService非常不方便,因此Q在开?/span>WebServiceӞ可以?/span>Axis2设ؓ热更新。在axis2.xml文g中找?/span><parameter name="hotupdate">false</parameter>Q将false改ؓtrue卛_?/span> 3. 在浏览器中测?/span>WebServiceӞ如果WebServiceҎ有参敎ͼ需要?/span>URL的请求参数来指定?/span>WebServiceҎ参数的|h参数名与Ҏ参数名要一_例如Q要试getGreetingҎQ请求参数名应ؓnameQ如上面?/span>URL所C?/span> 4. 发布WebService?/span>pojo目录只是默认的,如果读者想在其他的目录发布WebServiceQ可以打开axis2.xml文gQƈ?/span><axisconfig>元素中添加如下的子元素: 上面的配|允许在<Tomcat安装目录>"webapps"axis2"WEB-INF"my目录中发?/span>WebService。例如,本例中?/span>SimpleService.class复制?/span>my目录中也可以成功发布Q但要删?/span>pojo目录中的SimpleService.classQ否?/span>WebService会重名)?/span>
三?/span> ?/span>Java实现调用WebService的客LE序 WebService是ؓE序服务的,只在览器中讉KWebService是没有意义的。因此,在本节?/span>Java实现了一个控制台E序来调用上一节发布的WebService。调?/span>WebService的客L代码如下Q?/span>
q行上面的程序后Q将在控制台输出如下的信息: 在编写客L代码时应注意如下几点Q?/span> 1. 客户端代码需要引用很?/span>Axis2?/span>jar包,如果读者不太清楚要引用哪个jar包,可以?/span>Eclipse的工E中引用Axis2发行包的lib目录中的所?/span>jar包?/span> 2. 在本例中使用?/span>RPCServiceClientcȝinvokeBlockingҎ调用?/span>WebService中的Ҏ?/span>invokeBlockingҎ有三个参敎ͼ其中W一个参数的cd?/span>QName对象Q表C调用的方法名Q第二个参数表示要调用的WebServiceҎ的参数|参数cd?/span>Object[]Q第三个参数表示WebServiceҎ的返回值类型的Class对象Q参数类型ؓClass[]。当Ҏ没有参数ӞinvokeBlockingҎ的第二个参数g能是nullQ而要使用new Object[]{}?/span> 3. 如果被调用的WebServiceҎ没有q回|应?/span>RPCServiceClientcȝinvokeRobustҎQ该Ҏ只有两个参数Q它们的含义?/span>invokeBlockingҎ的前两个参数的含义相同?/span> 4. 在创?/span>QName对象ӞQNamecȝ构造方法的W一个参数表C?/span>WSDL文g的命名空间名Q也是<wsdl:definitions>元素?/span>targetNamespace属性|下面?/span>SimpleServicecȝ成的WSDL文g的代码片D:
四、用wsdl2java化客L的编?/span> 也许有很多读者会?#8220;有没有搞错啊Q只调用两个WebServiceҎ用要写这么多代码Q太ȝ?#8221;?/span> 不过q好Axis2提供了一?/span>wsdl2java.bat命o可以ҎWSDL文g自动产生调用WebService的代码?/span>wsdl2java.bat命o可以?/span><Axis2安装目录>"bin目录中找到。在使用wsdl2java.bat命o之前需要设|?/span>AXIS2_HOME环境变量Q该变量值是<Axis2安装目录>?/span> ?/span>Windows控制台输出如下的命o行来生成调用WebService的代码: %AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/SimpleService?wsdl -p client -s -o stub 其中-url参数指定?/span>wsdl文g的\径,可以是本地\径,也可以是|络路径?/span>-p参数指定了生成的Javacȝ包名Q?/span>-o参数指定了生成的一pd文g保存的根目录。在执行完上面的命o后,读者就会发现在当前目录下多了个stub目录Q在."stub"src"client目录可以扑ֈ一?/span>SimpleServiceStub.java文gQ该文g复杂调用WebServiceQ读者可以在E序中直接用这个类Q代码如下:
上面的代码大大简化了调用WebService的步骤,q代码更加z。但要注意的是,wsdl2java.bat命o生成?/span>StubcdWebServiceҎ的参数都装在了相应的类中,cd为方法名Q例如,getGreetingҎ的参数都装在了GetGreetingcMQ要惌?/span>getGreetingҎQ必d创徏GetGreetingcȝ对象实例?/span> 五、?/span>C#调用WebService 从理Z_WebService可以被Q何支?/span>SOAP协议的语a调用。在Visual Studio中?/span>C#调用WebService是在所有语a中最Ҏ实现的(VB.net的调用方法类|也同样很单)?/span> 新徏一?/span>Visual Studio工程Qƈ在引?/span>Web服务的对话框中输入如下的URLQƈ输入Web引用名ؓ“WebService”Q?/span> http://localhost:8080/axis2/services/SimpleService?wsdl 然后引用Web服务的对话框׃昄?/span>WebService中的所有的ҎQ如?/span>5所C?br />
在完成上面的工作后,只需要如下三?/span>C#代码可以调?/span>getGreeting?/span>getPriceҎQƈ昄q两个方法的q回| ?/span>.net解析WSDL文g时直接将getGreetingҎ的参数映ؓStringcdQ因此,可以直接q行传倹{?/span>
?
?/span>3和图4分别昄?/span>getGreeting?/span>getPriceҎ的测试结果?br />
import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class RPCClient
{
public static void main(String[] args) throws Exception
{
// 使用RPC方式调用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/SimpleService");
options.setTo(targetEPR);
// 指定getGreetingҎ的参数?/span>
Object[] opAddEntryArgs = new Object[] {"h"};
// 指定getGreetingҎq回值的数据cd的Class对象
Class[] classes = new Class[] {String.class};
// 指定要调用的getGreetingҎ及WSDL文g的命名空?/span>
QName opAddEntry = new QName("http://ws.apache.org/axis2", "getGreeting");
// 调用getGreetingҎq输Ҏ的返回?/span>
System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]);
// 下面是调用getPriceҎ的代码,q些代码与调用getGreetingҎ的代码类?/span>
classes = new Class[] {int.class};
opAddEntry = new QName("http://ws.apache.org/axis2", "getPrice");
System.out.println(serviceClient.invokeBlocking(opAddEntry, new Object[]{}, classes)[0]);
}
}
443
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:ns="http://ws.apache.org/axis2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
targetNamespace="http://ws.apache.org/axis2">
<wsdl:types>
</wsdl:types>
</wsdl:definitions>
import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class StubClient
{
public static void main(String[] args) throws Exception
{
SimpleServiceStub stub = new SimpleServiceStub();
SimpleServiceStub.GetGreeting gg = new SimpleServiceStub.GetGreeting();
gg.setName("比尔");
System.out.println( stub.getGreeting(gg).get_return());
System.out.println(stub.getPrice().get_return());
}
}
?
MessageBox.Show( simpleService.getGreeting("比尔"));
MessageBox.Show(simpleService.getPrice().@return.ToString());
从上面的调用q程可以看出Q添?/span>Web引用的过E就相当于在Java中调?/span>wsdl2java.bat自动生成stubcȝq程。只是在调用stubcL?/span>C#有一定的区别Q但从M上来_都大大简化了调用WebService的过E?br />
转自Qhttp://www.aygfsteel.com/nokiaguy/
]]>
2008-7-9 cheungmine
1 问题的来源:我在WebService中无法连接Oracle10g
2 解决的办法: 9i: ORACLE_HOME 目录增加用户Authenticated Users (dq行的权? ? 10g: OracleClient10g 目录增加用户Authenticated Users (dq行的权?
ORACLE_HOME 是oracle安装的主目录Q?OracleClient10g?0g客户端安装的ȝ录?/p>
为目录增加用LҎ是在目录上右?>属?>安全->d->Q输入对象和名称框里输入Authenticated UsersQ?>选中允许dq行?/p>
我采用oradbi? 用于在WebService和Oracleq接。oradbi库是我写的开放源码的OCI装库,
旨在对大数据字段BLOB的读写提供更高效的访问,您可以在我的资源中下载?
当然建立对应的包Q就不用说了?br />
然后~译文g?br />
q入命o提示W下Q进入classes目录Q运行:wsgen -cp . WebServices.WSProvider
可以看到刚才的class 生成了几个java文g和class文g?br />
现在要做的是发布ws到http://localhost:8888/chinajash/WSProvider
而实际上的动作就是:Endpoint.publish("http://localhost:8888/chinajash/WSProvider",new WSProvider());
当然直接q行WSProvider ?br />
然后输入http://localhost:8888/JAVA-HE/WSProvider?wsdl
已l查看到生成的wsdl Qwebservice 描述语言Q?br />
也就是服务端OK了?br />
保持q行。编写一个测试客LQ?br />
首先选择目Q右键新?web服务客户端。其中ws url填入刚才生成的wsdl地址Q?br />
http://localhost:8888/JAVA-HE/WSProvider?wsdl
Q实际上Q和wsimport http://localhost:8888/JAVA-HE/WSProvider?wsdl 一L效果Q?br />
产生一个效果:在classes?按照 之前指定的名字空间生的包下Q目录结构)生成?个帮助class?br />
然后我们建立一个包 client 建立试文gQ?br />
q行q个试c:
Hi,hechangmin
输出了。顺利完成!
一点个人经验,你发布的地址最好写成可配置。还有就是wsdl 中会严格按照你指定的url来访问,比如你指定的127.0.0.1 那么你用本机IP的时候也许ƈ不能利讉K?br />