4.3.2 WebService代理中心UDDI的实现<o:p></o:p>
当本地网站发出查询请求后,如上文提及的结构图所示,是先将请求发送到
WebService的课件中心代理UDDI。其中,这个UDDI的作用是:存储各个网站的WebService信息地址,当有查询请求时,UDDI中心将会调用已经注册的WebService去搜索,当搜索完成时,会将搜索结果返回给用户。同时,用户可以通过uddi搜索有关的WebService。而在调用WebService的时候,有两种调用方式,一种是同步调用,另外一种是异步调用方式。
在使用同步调用方式的时候,
调用
WebService
往往会经历较长的时延,或者是得不到响应(原因可能是
Internet
的连接问题,带宽问题,对方服务器过于繁忙等)。这样,有可能在客户端这边,就会处于不能响应的停顿状态,使得程序在等待返回结果时被
“
挂起
”
,
处理请求的线程会一直被占用,直到方法调用结束。当前线程会一直等待调用完成。线程无事可做,只是等待,直至听到查询的返回。
这种情况对于用户来说是不可以接收的。
而异步调用方式则不同,它在当调用某个
WebService
而长期没有能得到回应时,会自动继续通过轮询查询机制,继续调用下一个
WebService
或者是其他资源。当某个
WebService
调用完成时,会发出一个回调信号,告诉调用者,调用已经完成。两种方式调用如图
<o:p></o:p>
当我在设计好
.NET端的WebService后,在设计JSP客户端调用WebService时,发现了一个问题,那就是,在很多非.NET语言中,并没有象.NET中的dataset的数据类型。但经过我的摸索,发现由于WebService中传递的都是XML,因此可以将.NET端搜索出来的结果以XML的形式表达出来,而不是单纯的DATASET。于是我就想到可以将.NET端WebService返回的结果以字符串的形式输出,就可以很好地解决这个问题。
因此,我选择用字符串的方式,将调用返回的
XML
以字符串的方式返回给
Java
的客户端。
4.4
Jsp客户端的设计
最后是Jsp客户端的设计。在这部分,我采用了前文提到的AXIS进行该部分的实现。 在实现前,必须要先产生客户端的STUB代理类,对XML进行反序列化,使得Java端能正
确识别解释
XML
。其中分为以下几个步骤:
1)
安装好有关的软件:
除了要安装
Axis
外,为了对
XML
进行解释,同时要安装
Xerces.Xerces
也是
Apache
组织开发的免费开放代码的软件,目的是可以高效地进行对
Java
中涉及
XML
的部分进行解释(可在
http://apache.org
上下载)。
<o:p></o:p>
2) 使用WSDL2JAVA工具产生有关的stub代理类。
在AXIS中,有两套工具可以产生有关的代理类,分别为WSDL2Java和Java2WSDL。前者用于将已知的WSDL WEB描述文件中自动产生STUB代理类,后者是将已经存在的Java类自动产生相关的wsdl文件,用来将已有的程序转变为WebService。而在我的设计中,由于是由.net 端提供WebService,由JSP端作为客户端进行调用,因此它们的关系如下图所示:
<o:p></o:p>
从上面的图可以看到,要使用Java提供的WSDL2Java工具,对由.net产生的wsdl文
件进行解释。采用的方法如下:
先获得WEBSERVICE课件搜索代理UDDI(MSEARCH.ASM)的wsdl文件,输入:
http://localhost/msearch/msearch.asmx?wsdl
<o:p></o:p>
之后获得的
wsdl文件。
接着,就可以运用WSDL2Java工具了。<o:p></o:p>
c:\java org.apache.axis.wsdl.WSDL2Java –package msearch http://localhost/msearch/msearch.asmx?WSDL
运行完成后,会在
msearch
目录下自动产生
stub
的代理类。
4
)
实现
JSP
的客户端
首先,要先导入已有的有关
axis
的类库及
XML
解释器
<%@ page language="java" import="msearch.*,javax.xml.parsers.*,org.w3c.dom.*,java.io.*,javax.xml.transform.*,org.xml.sax.*" %>
接着,初始化
STUB代理类的实例,调用WebService:
msearch.MsearchLocator binding=new MsearchLocator();<o:p></o:p>
try {<o:p></o:p>
msearch.MsearchSoap port=binding.getmsearchSoap();<o:p></o:p>
String str=port.query(sql);//传入sql查询语句,返回的结果存放在字符串str当中,<o:p></o:p>
为了能在 JSP客户端对调用返回的WebService中的XML解释,我使用了JAVA的DOM(XML文档对象模型)进行解释,因此,要初始化DOM对象。<o:p></o:p>
<o:p></o:p>
//初始化DOM对象 <o:p></o:p>
StringReader stringReader = new StringReader(str);<o:p></o:p>
InputSource inputSource = new InputSource(stringReader);<o:p></o:p>
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();<o:p></o:p>
DocumentBuilder builder=factory.newDocumentBuilder();<o:p></o:p>
Document doc=builder.parse(inputSource);<o:p></o:p>
doc.normalize();<o:p></o:p>
NodeList kejians =doc.getElementsByTagName("kejian");//提取每个kejian的结点集,<o:p></o:p>
for (int i=0;i<kejians.getLength();i++)<o:p></o:p>
{ <o:p></o:p>
……<o:p></o:p>
提取每个结点的值,并予以显示 <o:p></o:p>
<o:p></o:p>
} <o:p></o:p>
<o:p></o:p>
这样,就完成了对
.NET WebService
端的调用,并且正确的在
JSP
端予以显示。下面是有关部分的截图:
在输入查询条件后,提交后,返回的结果为:
<v:shapetype id="_x0000_t75"><v:stroke></v:stroke><v:formulas><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f><v:f></v:f></v:formulas><v:path></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype>
<o:p></o:p>
其中,由于我在设计的时候是在同一台机器上进行,所以在上面的结果中,
localhost/kejiana
表示的是该数据是来自
kejiana
的数据库的,而
localhost/kejianb
表示的是该数据是来自
kejianb
的数据库的。,(待续)