分享
 
 
 

Web Service开发中对象数据类型的交换

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

作者:翁 彦

时间:2003-7-24

欢迎大家同我联系,enhydra_boy@tom.com

欢迎转载,转载请保留申明信息。

上次我谈了TOMCAT上如何快速开发Web service应用,并且举了个例子。但是传递的参数都是常见的数据类型,如果要传递复杂的数据类型,比如对象类型,那么应该如何来做呢。本篇,就是讨论这个问题。

我的方案是用一个string来实现,web service服务器端和客户端的复杂数据类型的交换。当然,这个string是一个xml格式字符串,它实现了复杂数据类型的存储。

那么,这个过程大致是这样的:

1 客户端发出SOAP的调用请求

2 服务端接受,从数据库中取出数据,并按要求加工成一个XML字符串

3 客户端接受xml字符串,并且解析出其中的信息。

反之,亦然。说道这里,应该说,这样的实现更本不难。那么,我们要解决的问题,是一套快速的开发方案,java开发中,使用对象来存储复杂的数据类型,vb中也有类的概念,那么当不同开发工具编写的程序进行数据交互通信的话,应该采用什么技术可以保证软件的开发速度和质量呢?这就是笔者本文的目的。

笔者认为,采用xml的专业设计工具来设计数据结构,利用第三方的开发工具,自动生成对应开发平台的源代码。这是较为快速和可靠的开发方法。

JAVA和VB都有相应的自动生成工具。JAVA是SUN Web Service Developer pack, VB有Microsoft SOAP ToolKit。简单说明如下:

1 利用XML SPY(XML设计工具)设计一个schema文件。

2 SUN Web Service Developer pack中jaxb可以根据schema自动生成java代码,编译成class文件。可以实现java程序把对象信息直接parse成xml字符串,和把xml字符串装载进来,初始化对象信息。

3 XML SPY把schema转换成xdr文件(xml data抽象文件),SOAP Toolkit中的Soap Message Object Generator自动生成VB类代码。功能同上。

下面,就让我们开始实践。

第一步,XML SCHEMA的设计

启动xml spy(如没有安装,下载并安装),新建一个schema文件,所有的设计都是可视化的。

保存,并得到一个EmployeeRoot.xsd文件。

第二步,自动生成java源程序。

先下载SUN Web Service Developer pack 1.1,安装并且按照文档配置环境。

在command窗口中,运行 %JAXB_HOME%\bin\xjc.bat EmployeeRoot.xsd -p com.sam.util.emp。命令成功后,会自动生成java源文件。

第三步,编译并且生成class代码。

在command窗口中,运行 %JAVA_HOME%\bin\javac com\sam\util\emp\*.java com\sam\util\emp\impl\*.java。

可以再运行jar命令打包。也可以运行javadoc为你的类生成技术文档。

第四部,建立一个Web Service,用于测试。

本例中,笔者使用的平台是TOMCAT+AXIS,大家可以看http://www.csdn.net/Develop/read_article.asp?id=19782 了解具体的配置。注意,请先把jaxb和jaxp的类库复制到$TOMCAT_HOME/axis/web-inf/libs下面。主要有:jaxb-api.jar, jaxb-libs.jar, jaxb-ri.jar, jaxb-xjc.jar, jaxp-api.jar。并把第三步得到的类库包也复制过来。

在axis目录下,创建一个EmpService.jws文件,代码如下:

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.math.BigDecimal;

import javax.xml.bind.JAXBContext;

import javax.xml.bind.JAXBException;

import javax.xml.bind.Marshaller;

import javax.xml.bind.Unmarshaller;

import javax.xml.transform.stream.*;

import java.io.StringReader;

import java.io.StringWriter;

import com.sam.util.emp.*;

public class EmpService {

public String GetEmployees()

{

StringWriter sOut=new StringWriter();

try {

// create a JAXBContext capable of handling classes generated into

JAXBContext jc=

JAXBContext.newInstance("com.sam.util.emp" );

Unmarshaller u= jc.createUnmarshaller();

StringBuffer xmlStr=new StringBuffer

("<Employees><Employee><FirstName></FirstName>

<MiddleName></MiddleName><LastName></LastName><SSN>

</SSN></Employee><Version></Version></Employees>");

Employees emps=(Employees)u.unmarshal(

new StreamSource(new StringReader(

xmlStr.toString())));;

emps.getEmployee().clear();

Employee emp=new com.sam.util.emp.impl.EmployeeImpl();

emp.setFirstName("John");

emp.setMiddleName("");

emp.setLastName("Bob");

emp.setSSN("555-111");

emps.getEmployee().add(emp);

emp=new com.sam.util.emp.impl.EmployeeImpl();

emp.setFirstName("Tom");

emp.setMiddleName("");

emp.setLastName("Bill");

emp.setSSN("567-281");

emps.getEmployee().add(emp);

Marshaller m = jc.createMarshaller();

m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT,

Boolean.TRUE );

StreamResult result = new StreamResult(sOut);

m.marshal(emps,result);

//System.out.println(sOut.toString());

} catch( JAXBException je ) {

je.printStackTrace();

return "";

}

return sOut.toString();

}

}

运行http://localhost:8080/axis/EmpService.jws?wsdl, 可以看到该Service文件对应的wsdl接口。

第五步,利用xml spy中的convert dtd/schema,将employeeroot.xsd 转换成xml data文件(Employeeroot.xdr)。

转换出来的文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<!-- edited with XML Spy v4.4 U (http://www.xmlspy.com) by weng yan (e-mao-e) -->

<!--XML-Data generated by XML Spy v4.4 U (http://www.xmlspy.com)-->

<Schema name="Untitled-schema" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">

<ElementType name="Employee" model="closed" content="eltOnly" order="seq">

<group minOccurs="1" maxOccurs="1" order="seq">

<element type="FirstName" minOccurs="1" maxOccurs="1"/>

<element type="MiddleName" minOccurs="1" maxOccurs="1"/>

<element type="LastName" minOccurs="1" maxOccurs="1"/>

<element type="SSN" minOccurs="1" maxOccurs="1"/>

</group>

</ElementType>

<ElementType name="Employees" model="closed" content="eltOnly" order="seq">

<AttributeType name="xmlns" dt:type="string"/>

<attribute type="xmlns"/>

<group minOccurs="1" maxOccurs="1" order="seq">

<element type="Employee" minOccurs="1" maxOccurs="*"/>

<element type="Version" minOccurs="1" maxOccurs="1"/>

</group>

</ElementType>

<ElementType name="FirstName" model="closed" content="textOnly" dt:type="string"/>

<ElementType name="LastName" model="closed" content="textOnly" dt:type="string"/>

<ElementType name="MiddleName" model="closed" content="textOnly" dt:type="string"/>

<ElementType name="SSN" model="closed" content="textOnly" dt:type="string"/>

<ElementType name="Version" model="closed" content="textOnly" dt:type="string"/>

</Schema>

第六步,启动Visual Basic工程,如果安装过Soap ToolKit3的话,可以看到在Visual Basic中有一个add-in程序,叫Microsoft SOAP Messaging Object Generator,利用这个工具可以自动得到对应的vb类代码。利用这个工具,生成VB类代码,并且编译成一个ActiveX DLL。关于具体的内容,以后,我会在SOAP TOOLKIT工具使用介绍中专门解释。

第七步,编写客户端测试程序。在屏幕上放置一个文本框text1和list框list1。放置一个按钮cmdRead。

编写代码如下:

Private Sub cmdRead_Click()

On Error Resume Next

Dim SoapClient As Object

Dim sResult As String

Set SoapClient = CreateObject("MSSOAP.SoapClient30")

Call SoapClient.MSSoapInit2(Text1.Text, "", "", "EmpService", "")

If Err.Number <> 0 Then

MsgBox SoapClient.FaultString, vbExclamation

Exit Sub

End If

' Now the client can call an operation listed in the portType element

' specified when calling mssoapinit().

sResult = SoapClient.GetEmployees()

If Err.Number <> 0 Then

MsgBox SoapClient.FaultString, vbExclamation

Exit Sub

End If

Dim oSoap As MSSMO.ISoapMessagePart

Dim oDom As MSXML2.DOMDocument30

Dim oEmps As EmployeesRoot.Employees

Dim oEmp As EmployeesRoot.Employee

'now we parse the xml data into our class

Set oDom = New MSXML2.DOMDocument30

If oDom.loadXML(sResult) Then

Set oEmps = New EmployeesRoot.Employees

Set oSoap = oEmps

For Each oXMLNode In oDom.childNodes

If oXMLNode.nodeType = NODE_ELEMENT Then

If _

oXMLNode.baseName = oSoap.ElementName And _

oXMLNode.namespaceURI = oSoap.namespaceURI _

Then

Set oSoap.Element = oXMLNode

Exit For

End If

End If

Next

List1.Clear

For Each oEmp In oEmps.Employee

List1.AddItem oEmp.SSN & vbTab & oEmp.FirstName & "," & oEmp.MiddleName & "," & oEmp.FirstName

Next

End If

End Sub

运行,测试结果如下:

总结,通过这个例子,笔者认为,它为我们开发带来了一种新的概念和思路。利用xml进行数据结构的设计,而代码是基于设计的模式自动得到,采用这种开发方法使得,设计人员可以把精力集中在数据模型和业务逻辑上,而且,代码的维护成本也大大降低。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有