- 浏览: 111664 次
- 性别:
文章分类
- 全部博客 (390)
- java开发 (0)
- Struts2框架 (0)
- Spring3框架 (0)
- Spring4框架 (0)
- Hibernate3框架 (0)
- Hibernate4框架 (0)
- jQuery前台技术 (0)
- ExtJs3前台技术 (2)
- ExtJs4前台技术 (0)
- javascript脚本语言 (0)
- Oracle数据库 (0)
- MySQL数据库 (0)
- SQL Server数据库 (0)
- JSTL与EL (0)
- Ajax技术 (0)
- DWR技术 (0)
- Ibatis技术 (0)
- Mybatis技术 (0)
- JBPM工作流 (0)
- xstream技术 (0)
- 框架整合技术 (0)
最新评论
webservice系列1---基于web工程上写一个基本数据类型的webservice
preparation
1.在阅读本机之前你需要看以下相关知识:
JDBC;
JDBC的介绍这里就不说了,网上忒多的资料了,这个也是做java接触数据库时必会的
ibatis;
可以参考我之前的博客http://www.cnblogs.com/java-pan/archive/2012/03/21/ibatis.html
XStream;
可以参考我之前的博客http://www.cnblogs.com/java-pan/archive/2011/10/25/Object_xml.html
axis;
可以参考我之前的博客http://www.cnblogs.com/java-pan/archive/2011/11/25/axis_webservice.html
2.项目结构
myeclipse:6.5 tomcat:5.0 system:win7 JDK:项目的版本是1.5 编译采用的是1.4
说明:本节介绍的是基于axis的webservice,采用的版本为axis1.4
3.下载项目中用到的jar包
http://files.cnblogs.com/java-pan/lib-axis1.4.rar
以上链接包含下面的所有包。下载的jar包主要包含以下几部分:
(1)oracle数据库驱动包 :classes12.jar
(2)ibatis包:ibatis-2.3.4.jar
(3)xstream-1.2.1.jar
(4)axis包(从以下链接下载http://mirror.bjtu.edu.cn/apache/ws/axis/1_4/ 下载后解压把lib下所有包导入)
(5)activation.jar和mail.jar 建议导入的包
以上除最后一个jar包外,其它的程序运行必须导入。(可能axis不需要导入所有的包,不过我们就全部导入好了)
项目jar包的详细列表如下:
说明:lib下一共中13个jar包,截图的图片也有13个jar包,但是博客发布后显示的只有8个jar包,可以图片另存为看到所有的jar包。
4.class&mthod
JDBC:DriverManager、Connection、PreparedStatement、ResultSet
DriverManager:
getConnection(String url, String user, String password)获得一个Connection对象,参数依次为数据库驱动的url、用户名、密码
Connection:
prepareStatement(String sql)获得一个预处理对象PreparedStatement
PreparedStatement:
executeQuery()执行查询操作,返回一个结果集对象ResultSet,不要传入任何参数
ResultSet:
next()返回一个布尔类型的值,用于判断是否还有记录
Ibatis:SqlMapClient、SqlMapClientBuilder
SqlMapClient:
SqlMapClient buildSqlMapClient(Reader reader)传入一个reader对象,创建一个SqlMapClient 对象
startTransaction();开始事务
getCurrentConnection()获取当前连接,回滚事务的时候用到
endTransaction结束事务
SqlMapClientBuilder:
queryForObject(String s, Object obj)第一个参数为实体类对应的配置文件的id属性,第二个为传入的参数,此方法的返回值是一个Object对象
xstream:XStream
XStream:
alias(String name, Class type)设置节点的别名
alias(String name, Class type)设置某一元素节点的别名
toXML(Object obj)把对应的obj转换为xml格式的字符串
其他类:Reader、Resources、StringBuffer
Reader:java I/O对象,用于读取字符流的抽象类,这里就不再介绍,请查看JDK帮助文档
Resources:此类为ibatis的jar包中的类,非JDK的类
getResourceAsReader(String resource)对于resource路径的文件,获得一个Reader对象
StringBuffer:线程安全的可变字符序列
append(String str)将指定的字符串追加到此字符序列
toString()返回此序列中数据的字符串表示形式
start
新建一个web工程,项目命名为WebService,按照工程目录新建对应的文件如下:
实体类-Dept.java
package com.bean; /** * *Module: Dept.java *Description: 写一个oracle数据库自带的部门表dept的javabean *Company: *Author: pantp *Date: May 1, 2012 */ public class Dept { public int deptNo; public String dName; public String loc; public int getDeptNo() { return deptNo; } public void setDeptNo(int deptNo) { this.deptNo = deptNo; } public String getDName() { return dName; } public void setDName(String name) { dName = name; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } }数据库连接文件-ConnectDataBase.java
ConnectDataBase package com.cn; import java.io.IOException; import java.io.Reader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; /** * *Module: ConnectDataBase.java *Description: 数据库连接类,采用两种方式:1.JDBC 2.Ibatis框架 *Company: *Author: pantp *Date: May 1, 2012 */ public class ConnectDataBase { //采用JDBC的方式连接数据 private final static String USERNAME = "scott"; private final static String PASSWORD = "orcl"; private final static String URL = "jdbc:Oracle:thin:@localhost:1521:orcl"; private final static String DRIVER = "oracle.jdbc.driver.OracleDriver"; static Connection conn = null; // 获取连接 static { // 加载驱动 try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 获得连接对象conn try { conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); } catch (SQLException e) { e.printStackTrace(); } } //提供一个方法供外部调用,获得JDBC连接对象conn public static Connection getConnection() { return conn; } // 定义ibatis映射文件的位置,写配置文件的完整路径 private static String resource = "com/ibatis/SqlMapConfig.xml"; private static SqlMapClient sqlMapClient = null; static { try { Reader reader = Resources.getResourceAsReader(resource); sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); } catch (IOException e) { e.printStackTrace(); } } //提供一个方法供外部调用,获得Ibatis的连接对象sqlMapClient public static SqlMapClient getSqlMapClient(){ return sqlMapClient; } }
实体类对应的映射文件-Dept.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- author:pantp date:2012/05/01 description:javabean对应的xml配置文件 --> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap> <typeAlias alias="Dept" type="com.bean.Dept" /> <!-- 精确查询 按照条件查询记录 按照部门编号DEPTNO查询 --> <select parameterClass="int" resultClass="Dept" id="selectById"> select deptno,dname,loc from dept where deptno=#deptNo# </select> </sqlMap>数据库连接属性文件-SqlMap.properties
driver=oracle.jdbc.driver.OracleDriver url=jdbc:Oracle:thin:@127.0.0.1:1521:orcl username=scott password=orclibatis核心配置文件-SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- author:pantp date:2012/05/01 description:Ibatis框架的核心配置文件,主要是数据库连接属性文件和实体类和表的映射文件引入进来 --> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <!-- 数据库连接的属性文件 --> <properties resource="com/ibatis/SqlMap.properties" /> <transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property value="${driver}" name="JDBC.Driver" /> <property value="${url}" name="JDBC.ConnectionURL" /> <property value="${username}" name="JDBC.Username" /> <property value="${password}" name="JDBC.Password" /> </dataSource> </transactionManager> <!-- 实体类和数据库表的映射 --> <sqlMap resource="com/ibatis/Dept.xml" /> </sqlMapConfig>定义查询服务的接口文件-IQueryInfoSV.java
package com.interfaces; import java.sql.SQLException; /** * *Module: IQueryInfoSV.java *Description: 定义查询的接口 *Company: *Author: pantp *Date: May 1, 2012 */ public interface IQueryInfoSV { //JDBC public abstract String queryDept1(int deptNo) throws SQLException; //ibatis public abstract String queryDept2(int deptNo) throws SQLException; }定义查询服务的实现类-QueryInfoSVImpl.java
package com.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import com.bean.Dept; import com.cn.ConnectDataBase; import com.ibatis.sqlmap.client.SqlMapClient; import com.interfaces.IQueryInfoSV; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; import com.thoughtworks.xstream.io.xml.XppDriver; import java.sql.SQLException; /** * *Module: QueryInfoSVImpl.java *Description: 根据部门编号查询oracle自带的dept表,提供两种查询方式:1.JDBC 2.Ibatis *Company: *Author: pantp *Date: May 1, 2012 */ public class QueryInfoSVImpl implements IQueryInfoSV { // 采用JDBC方式连接数据库的查询操作 public String queryDept1(int deptNo) throws SQLException { // 获取JDBC的连接 Connection conn = ConnectDataBase.getConnection(); // 拼装SQL语句 String sql = "select deptno,dname,loc from dept where deptno=" + deptNo; // 获得预处理对象pst PreparedStatement pst = conn.prepareStatement(sql); // 查询结果集 ResultSet rs = pst.executeQuery(); // 采用next()方法取得数据库数据,deptNo是逐渐采用deptNo查询,要么没有查到数据,要么只能查到一条数据 String result = ""; Dept dept = null; while (rs.next()) { dept = new Dept(); dept.deptNo = deptNo; dept.dName = rs.getString("dName"); dept.loc = rs.getString("loc"); } result = getXML(dept); return result; } // 采用ibatis连接数据库并按部门编号精确查找 public String queryDept2(int deptNo) throws SQLException { // 获得ibatis的连接对象sqlMapClient SqlMapClient sqlMapClient = ConnectDataBase.getSqlMapClient(); Dept dept = null; try { sqlMapClient.startTransaction();// 开始事务 // 执行查询 此处的"selectById"对应Dept.xml文件中select标签的id属性 dept = (Dept) sqlMapClient.queryForObject("selectById", new Integer(deptNo)); sqlMapClient.commitTransaction();// 提交事务 } catch (SQLException e) { try { sqlMapClient.getCurrentConnection().rollback();// 回滚事务 } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); } finally { try { sqlMapClient.endTransaction();// 结束事务 } catch (SQLException e) { e.printStackTrace(); } } // 组装xml报文并返回 return getXML(dept); } // 采用XStream方式组装XML public static String getXML(Dept dept) { // 用于保存XML的内容 String xmlbody = ""; // 用于保存XML的头部 String xmlhead = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; if (null != dept) { // 构造一个xstream对象,此种构造方式解决下划线站两个字符的问题 XStream xstream = new XStream(new XppDriver( new XmlFriendlyReplacer("-_", "_"))); // 设置别名,不设置的话显示为Dept_Info显示为com.bean.Dept xstream.alias("DEPT_INFO", Dept.class); xstream.aliasField("DEPTNO", Dept.class, "deptNo"); xstream.aliasField("DNAME", Dept.class, "dName"); xstream.aliasField("LOC", Dept.class, "loc"); // 把实体类转换为XML xmlbody = xstream.toXML(dept); } else { // 处理根据编号没有查询到数据的情况 StringBuffer sb = new StringBuffer(); sb .append("<DEPT_INFO><DEPTNO></DEPTNO><DNAME></DNAME><LOC></LOC></DEPT_INFO>"); xmlbody = sb.toString(); } return xmlhead + xmlbody; } }测试类-Test1.java 用于测试JDBC和ibatis的数据库连接是否正常
package com.test; import java.sql.SQLException; import com.impl.QueryInfoSVImpl; import com.interfaces.IQueryInfoSV; /** * *Module: Test1.java *Description: 测试JDBC和Ibatis数据库查询是否正常 *Company: *Author: ptp *Date: May 1, 2012 */ public class Test1 { // 测试数据库是可以正常查询 public static void main(String[] args) throws SQLException { int deptNo = 10; test1(deptNo); test2(deptNo); } //测试JDBC方式连接数据库是否正常 public static void test1(int deptNo) throws SQLException { IQueryInfoSV query = new QueryInfoSVImpl(); String dept = query.queryDept1(deptNo); System.out .println("\n===============采用JDBC方式查询数据库连接正常 author<pantp>=======\n"); System.out.println(dept); System.out .println("\n===============采用JDBC方式查询数据库连接正常==================\n"); } //测试ibatis方式连接数据库是否正常 public static void test2(int deptNo) throws SQLException { IQueryInfoSV query = new QueryInfoSVImpl(); String dept = query.queryDept2(deptNo); System.out .println("\n===============采用ibatis方式查询数据库连接正常 author<pantp>========\n"); System.out.println(dept); System.out .println("\n===============采用ibatis方式查询数据库连接正常==================\n"); } }测试类-Test2.java 用于测试webservice服务是否可以正常调用
package com.test; import java.net.MalformedURLException; import java.net.URL; import java.rmi.RemoteException; import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ServiceException; import org.apache.axis.client.Call; import org.apache.axis.encoding.XMLType; /** * *Module: Test2.java *Description: 项目中常用调用webservice方式有两种,stub桩的形式和动态调用,本次测试就用动态调用的方式 *Company: *Author: pantp *Date: May 1, 2012 */ public class Test2 { // 调用webservice public static void main(String[] args) { test2(); } /** * 动态调用接口访问webservice服务的步骤如下: * 1.创建service对象 * 2.创建url对象 * 3.创建call对象, * 4.调用webservice的方法 * 5.处理返回结果 */ public static void test2() { try { // 1.创建service对象,通过axis自带的类创建 org.apache.axis.client.Service service = new org.apache.axis.client.Service(); // 2.创建url对象 String wsdlUrl = "http://127.0.0.1:8080/WebService/services/queryInfo?WSDL";// 请求服务的URL URL url = new URL(wsdlUrl);// 通过URL类的构造方法传入wsdlUrl地址创建URL对象 // 2.创建服务方法的调用者对象call,设置call对象的属性 Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url);// 给call对象设置请求的URL属性 String serviceName = "queryDept2";//webservice的方法名 call.setOperationName(serviceName);// 给call对象设置调用方法名属性 call.addParameter("deptNo", XMLType.XSD_INT, ParameterMode.IN);// 给call对象设置方法的参数名、参数类型、参数模式 call.setReturnType(XMLType.SOAP_STRING);// 设置调用方法的返回值类型 // call.setTimeout(new Integer(5000));//设置超时限制 // 4.通过invoke方法调用webservice Integer deptNo = new Integer(50); String dept = (String) call.invoke(new Object[] { deptNo });// 调用服务方法 //5.打印返回结果 System.out .println("\n===============调用webservice成功(无安全机制) author<pantp>=======\n"); System.out.println(dept); System.out .println("\n===============调用webservice成功(无安全机制)==================\n"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ServiceException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } }
web.xml-项目配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>AxisServlet</servlet-name> <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <mime-mapping> <extension>wsdl</extension> <mime-type>text/xml</mime-type> </mime-mapping> <mime-mapping> <extension>xsd</extension> <mime-type>text/xml</mime-type> </mime-mapping> </web-app>
server-config.wsdd-webservice服务部署的配置文件
<?xml version="1.0" encoding="UTF-8"?> <deployment name="defaultClientConfig" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler" xmlns="http://xml.apache.org/axis/wsdd/"> <globalConfiguration name="GlobalConfiguration1" type="" regenerateElement="false"> <requestFlow name="RequestFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false"> <parameter name="scope" value="session" regenerateElement="false"/> </handler> <handler name="Handler2" type="java:org.apache.axis.handlers.JWSHandler" regenerateElement="false"> <parameter name="scope" value="request" regenerateElement="false"/> <parameter name="extension" value=".jwr" regenerateElement="false"/> </handler> </requestFlow> </globalConfiguration> <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper" regenerateElement="false"/> <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder" regenerateElement="false"/> <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" regenerateElement="false"/> <transport name="http" type="" regenerateElement="false"> <requestFlow name="RequestFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="URLMapper" regenerateElement="false"/> <handler name="Handler2" type="java:org.apache.axis.handlers.http.HTTPAuthHandler" regenerateElement="false"/> </requestFlow> </transport> <transport name="local" type="" regenerateElement="false"> <responseFlow name="ResponseFlow1" type="" regenerateElement="false"> <handler name="Handler1" type="LocalResponder" regenerateElement="false"/> </responseFlow> </transport> <service name="queryInfo" provider="java:RPC"> <!-- 服务类名 --> <parameter name="className" value="com.impl.QueryInfoSVImpl" /> <!-- 允许访问所有方法 --> <parameter name="allowedMethods" value="*" /> </service> </deployment>
result
发布项目,启动tomcat。
运行Test1.java中的main方法,测试JDBC和ibatis数据库查询是否正常,查询结果如下:
在浏览器访问发布的wsdl
输入如下地址:http://127.0.0.1:8080/WebService/services/queryInfo?WSDL
访问界面如图:
运行Test2类中的main方法,测试结果如下图:
webservice服务存在以下2个问题:
(1)如上图所示,按说在浏览器中可以正常的访问wsdl的话,就说明服务已经发布好了。为什么客户端调用会报如此错误呢?
(2)如果我把访问的127.0.0.1改为localhost就不能正常的访问wsdl了,这个是什么原因呢?
急需大虾出现解决小弟的问题,我也在努力的查找中。跪求ing。
源码:http://download.csdn.net/detail/xuxu198899223/5344482
问题定位及解决方法:
关于此博客中的问题一直未解决,心中的石头也一直未落地;
经过这两天的再一次拿出来查找问题、定位问题,终于得到了答案。
解决方式:把ConnectDataBase类中采用ibatis操作数据库的代码给去掉,然后再一次重新发布工程,启动tomcat,
此时,在IE浏览器可以正常的访问wsdl地址,采用webservice客户端形式(包括动态调用和stub桩的形式)也可以正常的调用webservice服务。
相关推荐
----------示例包括: 普通数据类型 ...使用axis2通过自编写的server端生成wsdl,通过wsdl生成服务(aar,将aar文件放入tomcat/webapps/axis2/WEB-INF/services下),再通过wsdl生成客户端,通过客户端调用服务
C#开发webservice接口,对客户端post服务的Json数据进行接收反馈 接收到的数据流转换成string类型,有其他需求对json解析,自己写个解析去查询下. 然后反馈json发送给请求端。
业务日志记录每个对业务数据的修改操作,包括操作人、时间、操作是否成功、业务数据的类型和Id 此template使用Sql Server数据库,启动后会自动创建表 数据库连接在PersonalManagerWS\Web.config 中配置
它描述了webservice中一些方法访问的契约(规范),谁都遵守该规范,即它描述了web service中能被访问方法的名,参数,参数的类型和返回值等等规定,其它平台上的程序必须按照wsdl中的规范来访问
创建一个具有单一类型定义的代码文件。 请使用 http:// URLs 作为命令行参数来引用 服务,或为本地文件创建一个 discomap 文档。 /verbose 指定 /sharetypes 开关时显示额外信息。 缩写形式为“/v”。 /...
该系统的主要思想是如果Web程序和WebService部署在同一台机器上,Web程序可以直接调用 WebService所对应的Java类。当然,也可以象第一个项目一样,直接通过HTTP SOAP协议调用WebService。在第二个项目中同时使用了这...
bank项目 描述了axis2如何发布webservice,如果...Set,Map,基本数据类型,自定义数据类型;其中自定义数据类型的包名和类名可以和发布方不同,只需要字段相 同就可以了。功能虽然强大,但运行效率比xfire稍逊一筹。
本实例演示了如何编写webService,以及在WEB和WinForm中对WebService接口的应用,接口涉及了多种数据类型:字符、布尔类型、DataSet类型等,对初学者有一定的帮助。
常用WebServices返回数据的4种方法比较方法。内有详细介绍。
多个系统数据交换: 跨平台语言的相互通信; 如:java 的客户端 和dotnet的服务器端的接口调用: 得到接口和方法 : 基于标准的协议,可编程语言; 服务器开发 api; 特点: 自包含:只要客户端支持http和xml...
1.9 带有复杂数据类型的web服务 23 1.10 多线程端点服务发布程序 27 1.11 下一章 30 第2章 全面了解wsdl 31 2.1 wsdl在web服务中的作用 31 2.2 wsdl文档结构 36 2.3 amazon e-commerce web服务 46 2.4 wsgen工具与...
鼠标放在一个连接上,会显示图片(类似tooltip) 使用microsoft.web.ui.webcontrols的TabStrip与IFame组件,达到页的切换效果 HttpModule 实现 ASP.Net (*.aspx) 中文简繁体的自动转换,不用修改原有的任何代码,直接部署...
1.基于这种风格架构,软件编写可以更简洁 → 一个地址通过请求方式控制请求方法 2.基于HTTP协议,支持多种消息格式,比如XML 、JSON 3.更易于实现缓存机制(第一次访问资源缓存,第二次访问资源,返回304客户端调用...
5. 响应一个请求的分层结构约定,列举几个示例(常规调用、Ajax调用、WebService调用、提供WebService暴露、硬件设备接口调用); 6. 验证代码质量的约定,如JUnit、EMMA、FindBugs、CheckStyle、PMD的使用;Hudson...
gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户...
4.5.2 显示数据类型转换 4.6 Opion语句 4.6.1 OptionExplicit 4.6.2 OptionStrict 4.6.3 OptionCompare 4.6.4 Optionlnfer 4.7 自定义类型Structure与Enum 4.8 表达式与运算符 4.8.1 算术运算符 4.8.2 赋值运算符 ...
WSCall4PB65.exe用于从WebService 地址中创建PowerBuilder6.5可以调用的用户对象,已经支持绝大部分的数据类型。
4.5.1 隐式数据类型转换 4.5.2 显示数据类型转换 4.6 Opion语句 4.6.1 OptionExplicit 4.6.2 OptionStrict 4.6.3 OptionCompare 4.6.4 Optionlnfer 4.7 自定义类型Structure与Enum 4.8 表达式与运算符 4.8.1 算术...
Web Service数据库同步系统的设计与实现 1 摘要 1 1引言 3 1.1课题背景 3 1.2国内外研究现状 4 1.3本课题研究的意义 6 1.4本课题的研究方法 6 2Web Service数据库同步原理 7 2.1 Web Service构成与特点 7 2.1.1 Web ...