关于wsdl属性nillable和minOccurs所表示的含义可以参考这篇文章
之前有在做项目时,正好遇到关于nillable和minOccurs这两个属性的问题,现在记录一下
服务端采用CXF,客户端则为.net的WPF。
服务端测试实体类代码如下
public class Child implements Serializable {
private String name;
private int age;
private int sex;
private Integer test1;
private Long test2;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public Integer getTest1() {
return test1;
}
public void setTest1(Integer test1) {
this.test1 = test1;
}
public Long getTest2() {
return test2;
}
public void setTest2(Long test2) {
this.test2 = test2;
}
}
生成的wsdl如下:
test1和test2 minOccurs 均为0,这表示该元素节点可以不出现,而 nillable 在wsdl中未出现,表示采用默认值false,表示该元素取值不能为空。
在看客户端根据wsdl生成出来的实体
java中Integer变成了C#的int,Long变成了long。我们知道值类型就算不赋值也是有默认初始值的,假如java中的test1和test2 均为null,那么服务端实体序列化到了客户端,这两个值将会变成0,稍后我们将会进行验证。另外还多出了两个Specified属性,该属性默认值为false,只有给它指定true的时候[元素节点]才会出现到soap报文中。
下面有两个例子
实例1.客户端代码如下:
服务端实现的功能是将客户端传输的child对象返回。
直接看服务端接收到的soap报文
信息: Inbound Message
---------------------------
<child xmlns="">
<age>18</age>
<name>name</name>
<sex>0</sex>
</child>
很惊喜有木有,两个test字段均没有被序列化,但是按照上面说的其实也在情理之中,因为Specified为false。
返回的soap报文:
信息: Outbound Message
---------------------------
<childList>
<age>18</age>
<name>name</name>
<sex>0</sex>
</childList>
因为服务端实现的功能是将客户端传输的child对象返回,所以返回的与接收的一致,但是我们看客户端接收到实体对象
what!!!两个test均为0,但是又是情理之中,因为这两个都为值类型,均具有初始值。
实例2.客户端代码如下:
代码与实例1差不多,但是将test1Specified赋值了true,这样test1元素节点将会出现在soap报文中。
信息: Inbound Message
---------------------------
<child xmlns="">
<age>18</age>
<name>name</name>
<sex>0</sex>
<test1>100</test1>
</child>
信息: Outbound Message
---------------------------
<childList>
<age>18</age>
<name>name</name>
<sex>0</sex>
<test1>100</test1>
</childList>
看test1和test2就能明白Specified的作用。
上面说到minOccurs 和 nillable 的作用,那么想要让元素取值可以为空,元素节点必须出现该怎么办。可以采用下面的方法。
@XmlElement(nillable = true, required = true)
public Integer getTest1() {
return test1;
}
@XmlElement(nillable = true, required = true)
public Long getTest2() {
return test2;
}
就是加上注解@XmlElement,其中nillable = true表示元素取值可以为空,required = true表示元素节点必须出现
看加上该注解后的wsdl:
与上面对比,test节点的 minOccurs=“0” 消失了,而nillable也被设置成了true。再看生成的客户端实体
Specified 字段没有了,而两个test字段也变成了可为空的值类型。
再看Soap报文和客户端接收到的对象
没被赋值的test2元素节点出来了,得到的值也为null了。
总结,nillable = true表示元素取值可以为空,在C#客户端生成的实体将会为可为空的值类型,
required = true表示元素节点必须出现,从而不会生成Specified字段。
另外以上只针对于值类型、包装类型