3、在VB下调用Web Service
下面我在VB环境下来调用下这个Web Service,笔者使用的是Visual Basic 6.0,要在VB下调用Web Service需要先安装Microsoft SOAP toolkit。
新建一个VB工程,然后把Microsoft Soap Type Library引用进来,如下图:
新建一个form1,添加一个按钮command1,在form1源代码窗口中整个拷贝如下代码:
Dim soap As MSSOAPLib.SoapClient
Private Sub Command1_Click()
MsgBox soap.sayHello()
MsgBox soap.welcome("老Z")
If Err <> 0 Then
MsgBox "Web Service调用失败: " + Err.Description
End If
End Sub
Private Sub Form_Load()
Set soap = New MSSOAPLib.SoapClient
On Error Resume Next
Call soap.mssoapinit("http://localhost:7001/WSDemo/HelloWorldWS?WSDL")
If Err <> 0 Then
MsgBox "初始化SOAP失败: " + Err.Description
End If
End Sub
然后运行工程,点击窗口上的按钮就开始调用前面部署的Web Service(确保Weblogic Server在运行中),成功的话会得到如下图的两个MessageBox:
四、使用非内建数据类型
前面例子中的Web Service方法中使用的参数和返回值都是String,类似String,int等数据类型是属于Weblogic web service所支持的内建类型,关于Weblogic web service所支持的内建数据类型请参见:http://e-docs.bea.com/wls/docs81/webserv/implement.html#1054236
所支持的XML非内建类型请参见:
http://e-docs.bea.com/wls/docs81/webserv/assemble.html#1060805
所支持的Java非内建数据类型请参见:
http://e-docs.bea.com/wls/docs81/webserv/assemble.html#1068595
WebLogic Server能够对内建数据类型进行XML与Java表示之间的转换。但是,如果你在web service操作中使用了非内建数据类型,那么你必须提供以下信息,以确保weblogic server能够正确地进行转换。
用于处理数据的Java表示与XML之间的转换的序列化类;
包含了数据类型Java表示的Java类;
数据类型的XML Schema表示;
web-services.xml部署描述文件中的数据类型映射信息。
Weblogic Server中带有servicegen和autotype Atn任务,这两个任务通过对web service的无状态EJB或者Java类后端组件的内省,从而自动生成上述部件。上述Ant任务能够处理许多非内建数据类型,所以大多数的开发者并不需要手工生成上述的部件。
有时,你可能也需要手工去创建非内建数据类型部件。因为你的数据类型可能很复杂,以致Ant任务不能正确生成前述部件。你也可能想要自己控制数据在XML和Java表示之间的转换过程,而不依赖Weblogic Server所使用的缺省转换程序。
本节将演示在Weblogic web service中如何处理非内建(自定义)的数据类型。
我们先编写一个数值Bean类UserInfo,如下:
package com.wnetw.ws.demo;
import java.util.*;
public class UserInfo{
private Integer userid;
private String username;
private String sex;
private Date birthday;
private int level;
private double salary;
private telcodes list;
public UserInfo(){}
public Integer getUserid(){
return userid;
}
public void setUserid(Integer userid){
this.userid = userid;
}
public String getUsername(){
return username;
}
public void setUsername(String username){
this.username = username;
}
public String getSex(){
return sex;
}
public void setSex(String sex){
this.sex = sex;
}
public Date getBirthday(){
return birthday;
}
public void setBirthday(Date birthday){
this.birthday = birthday;
}
public int getLevel(){
return level;
}
public void setLevel(int level){
this.level = level;
}
public double getSalary(){
return salary;
}
public void setSalary(double salary){
this.salary = salary;
}
public List getTelcodes(){
return telcodes;
}
public void setTelcodes (List telcodes){
this. telcodes = telcodes;
}
}
在前文中的后端组件类HelloWorldWS.java中增加一个方法:
public UserInfo getUserInfo(Integer userid){
UserInfo userinfo = new UserInfo();
userinfo.setUserid(userid);
userinfo.setUsername("李泽林");
userinfo.setSex("男");
userinfo.setBirthday(new Date());
userinfo.setLevel(2);
userinfo.setSalary(1000.51);
List telcodes = new ArrayList();
telcodes.add("123");
telcodes.add("321");
userinfo.setTelcodes (telcodes);
return userinfo;
}
在这个方法里,返回值是UserInfo,这是我们前面定义的数值Bean,由于这是非内建类型,而且也不属于受支持的非内建类型,所以需要我们必须自己来处理XML和UserInfo Java表示数据类型之间的转换。
在本文的例子中,我们使用Weblogic Server的autotype任务来做这件事情。我们先在build目录建一个autotype目录,然后在前文中ant完整脚本中的compile任务之后增加下述脚本:
<target name="gentypeinfo">
<autotype javatypes="com.wnetw.ws.demo.UserInfo"
targetNamespace=""
packageName="com.wnetw.ws.demo"
destDir="/autotype"
keepGenerated="true">
<classpath refid="classpath"/>
</autotype>
<copy todir="/classes">
<fileset dir="/autotype">
<include name="**/*.class"/>
</fileset>
</copy>
</target>
autotype Ant任务有几个常用属性,下面简要说明下:
javatypes:需要进行类型转换的非内建(自定义)数据类型java类,注意取值是全限定类名,不需要带上java或者class扩展名。如果存在多个这样的数据类型类,用逗号“,”隔开;
targetNamespace:在对数据类型映射到XML的时候使用的命名空间;
packageName:生成的序列化相关类的封装包;
destDir:生成的序列化相关类存放的目录;
keepGenerated:是否保留中间java源文件,取值为:true或者false。
关于autotype任务的详细信息请参考:
http://e-docs.bea.com/wls/docs81/webserv/anttasks.html#1080062
上述ant任务成功运行后就会生成build/autotype/目录下生成types.xml文件以及按包封装的数据转换类的源文件和class文件。
由于增加了自定义数据类型,所以我们还得更新source2wsdd任务脚本,以下是增加了自定义数据类型处理后的source2wsdd任务脚本:
<target name="genwsdd">
<source2wsdd javaSource="/com/wnetw/ws/demo/HelloWorldWS.java"
typesInfo="/autotype/types.xml"
ddFile="/wsddfiles/web-services.xml"
wsdlFile="/wsddfiles/HelloWorldWS.wsdl"
serviceURI="/HelloWorldWS">
<classpath refid="classpath"/>
</source2wsdd>
</target>
跟以前的脚本相比,增加了typesInfo属性来指定自定义数据类型的XML描述文件。
增加了对自定义数据类型支持后的完整脚本请参考本文代码下载文件。
按照第一节所述方法运行ant脚本build_wls_all.xml后,再部署buildpplications目录下的HelloWorldWS.ear。就可以按照以前说的方法进行测试了。
这一次在Weblogic Server自动生成的web service测试主页:
http://localhost:7001/WSDemo/HelloWorldWS
可以发现多了一个叫getUserInfo的方法连接,进入此方法的调用测试页面,调用此方法后就可以看到此web service方法的调用结果,以下是结果截图:
从调用测试结果页面可以看到,这一次的Return Value是:
com.wnetw.ws.demo.UserInfod235
这正是我们的web service方法返回值类型类型的一个对象,图中的下面也以SOAP消息的形式描述了调用的输入和返回结果。
我们接着修改测试类HelloWorldWSTest.java,