术语约定
文章中会反复出现[值类型]、[包装类型]、[普通引用类型]、[元素节点]和[元素取值]的表述
1> [值类型]指的是java和.NET中的基本数据类型,如:int;
2> [包装类型]指的是java中的包装类和.NET中的Nullable<T>类型,如:Integer、int?;
3> [普通引用类型]指的是除包装类型外的其它引用类型;
4> [元素节点]指的是xml文档中的一个标签节点,我们可以说[元素节点]是必输还是非必输,如:<Name>lubiao</Name>;
5> [元素取值]指的是xml标签节点的内容,我们可以说[元素取值]是空还是非空,如:<Name>lubiao</Name>表示元素取值不为空,<Name xsi:nil="true"/>表示元素取值为空;
1、首先来看minOccurs和Nillable的定义
minOccurs:表示XML文档中某个[元素节点] 是否可以不出现,默认值为1,表示必须出现
nillable:表示XML文档中某个[元素取值] 是否可以为空(形如:<name xsi:nil="true" />),默认值为false,表示不能为空
那么,minOccurs和nillable的组合形式就会有4种,如下:
例一,值类型:
<element name="id1" type="int" minOccurs="0" nillable="true"/>
<element name="id2" type="int" minOccurs="0" nillable="false"/>
<element name="id3" type="int" minOccurs="1" nillable="true"/>
<element name="id4" type="int" minOccurs="1" nillable="false"/>
例二,引用类型:
<element name="name1" type="string" minOccurs="0" nillable="true"/>
<element name="name2" type="string" minOccurs="0" nillable="false"/>
<element name="name3" type="string" minOccurs="1" nillable="true"/>
<element name="name4" type="string" minOccurs="1" nillable="false"/>
2、Java和.NET自动生成WSDL的规则
在实际开发时我们通常的做法是先编写Server端代码,然后利用工具自动生成wsdl描述,最后再利用工具读取wsdl进而生成客户端程序。那么用工具生成wsdl和用工具反向生成代理程序的规则是什么呢?下来对此进行实例分析:
2.1 先看.NET生成wsdl的规则
实验时所用的开发工具为VS 2010,用vs开发WebService的资料,百度搜索一大推,这里不赘述。
2.1.1、定义数据实体:Person.cs
public class Person
{
public int Id { get; set; } //值类型
public string Name { get; set; }//普通引用类型
public int? PhoneNbr { get; set; }//包装类型
}
2.1.2、定义服务类:WebService.cs
/// <summary>
///WebService 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
//如果使用设计的组件,请取消注释以下行
//InitializeComponent();
}
[WebMethod]
public string HelloWorld(int id,int? phoneNbr,string name,Person person) {
return "Hello World";
}
}
helloWorld方法有4个参数,前三个参数和Person类的三个属性是一样的,加入这三个参数的目的是进行对比测试。
2.1.3、查看生成的wsdl
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="HelloWorld">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="id" type="s:int" />
<!--nillable默认为false,minOccurs等于1:即id元素为必输,且值不能为空-->
<s:element minOccurs="1" maxOccurs="1" name="phoneNbr" nillable="true" type="s:int" />
<!--nillable等于true,minOccurs等于1:即phoneNbr元素为必输,但值可以为空-->
<s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" />
<!--nillable默认为false,minOccurs等于0:即name元素为非必输,但值不能为空-->
<s:element minOccurs="0" maxOccurs="1" name="person" type="tns:Person" />
<!--nillable默认为false,minOccurs等于0:即person元素为非必输,但值不能为空-->
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="Person">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Id" type="s:int" />
<!--nillable默认为false,minOccurs默认为1:即id元素为必输,且值不能为空-->
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<!--nillable默认为false,minOccurs等于0:即Name元素为非必输,但值不能为空-->
<s:element minOccurs="1" maxOccurs="1" name="PhoneNbr" nillable="true" type="s:int" />
<!--nillable默认为false,minOccurs等于1:即PhoneNbr元素为必输,但值可以为空-->
</s:sequence>
</s:complexType>
<s:element name="HelloWorldResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
</wsdl:definitions>
2.1.4、得出结论
* id参数和Person.Id属性都为值类型:[元素节点] 都必输,[元素取值] 都不能为空
* phoneNbr参数和Person.PhoneNbr属性都是包装类型:[元素节点] 都必输,但[元素取值] 都可以为空;
* name参数和Person.Name属性都是普通引用类型:[元素节点] 都可以不输,但[元素取值] 都不能为空;
* person参数是普通引用类型:[元素节点] 可以不输,但[元素取值] 不能为空。
2.2 再看Java的规则
首先,先熟悉在eclipse中快速开发webservice程序的步骤,参考链接:http://www.blogjava.net/parable-myth/archive/2010/08/03/327802.html,此次实验采用的就是这种快速开发方式(注:不同的框架和工具会可能会有不同的生成规则),所用ecllipse版本为:
Version: Juno Service Release 1
Build id: 20121004-1855
2.2.1、定义数据实体:Person.java
package com.lubiao.axis;
public class Person implements java.io.Serializable {
private int id;//编号,值类型
private java.lang.String name;//姓名,普通引用类型
private Integer phoneNbr;//电话,包装类型
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public java.lang.String getName() {return name;}
public void setName(java.lang.String name) {this.name = name;}
public Integer getPhoneNbr() {return phoneNbr;}
public void setPhoneNbr(Integer phoneNbr) {this.phoneNbr = phoneNbr;}
}
2.2.2、定义服务类:WebServiceTest.java
package com.lubiao.axis;
public class WebServiceTest{
public String helloWorld(int id,Integer phoneNbr,String name,Person person){
return "Hello World";
}
}
helloWorld方法有4个参数,前三个参数和Person类的三个属性是一样的,加入这三个参数的目的是进行对比测试。