http://docs.sun.com/app/docs/doc/820-1072/ahigx?l=zh_TW&a=view
对一些特殊的
data type
在
java
和
web service xml
之间的绑定和映射进行了详细的讲解
。下面只是对其中一些部分进行翻译。
对那些基本类型(如
int, long, double, string
),不需要添加任何的
annotation
就可以进行把
java data type
映射到
web service schema data type
,即使你是用自定义的
class
来包装基本类型
(象下面例子中的
user class
)
举个例子:
User class
public
class
User {
public
Long
id
;
public
String
name
;
public
int
age
;
}
@WebService
public
class
HelloWS {
@WebMethod
public
String getHello(String name){
return
"hello "
+ name;
}
@WebMethod
public
User getUser(
long
id){
return
null
;
}
}
上面的代码生成的
wsdl
中与
datatype
相关的代码为:
<xs:complexType name='getUserResponse'>
<xs:sequence>
<xs:element minOccurs='0' name='return' type='tns:user'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='user'>
<xs:sequence>
<xs:element minOccurs='0' name='id' type='xs:long'/>
<xs:element minOccurs='0' name='name' type='xs:string'/>
<xs:element name='age' type='xs:int'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='getHelloResponse'>
<xs:sequence>
<xs:element minOccurs='0' name='return' type='xs:string'/>
</xs:sequence>
</xs:complexType>
从上面可以看到基本类型的相互转换很容易。
但总是有一些特殊的
data type
,如
1.
BigDecimal Type
2.
java.net.URI Type
3.
Duration
4.
Binary Types
5.
XMLGregorianCalendar Type
6.
UUID Type
7.
Typed Variables
8.
Collections Types
9.
Array Types
10
.
Enum type
这些
datatype
,
JAX-WS 2.0
对它映射转换成
web service schema data type
有时必须要借助
JAXB
的
annotation
!!
(因此,
classpath
要加入
jaxb-api.jar
)
下面只介绍
binary type, collections type, array type and enum type
如何映射,其他的请参看文章开头给的
link
。
Binary Type
对于该类型,
JAXB 2.0
提供了
annotation @XmlMimeType
来定义。
先举一个Mapping
java.awt.Image
without
@XmlMimeType
的例子:
//-- Java code fragment
public class Claim {
public java.awt.Image photo;
}
//-- Schema fragment
<xs:complexType name="claim">
<xs:sequence>
<xs:element name="photo" type="xs:base64Binary" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
再举一个Mapping
java.awt.Image
with
@XmlMimeType
的例子:
//-- Java code fragment
public class Claim {
@XmlMimeType("image/gif")
public java.awt.Image photo;
}
//-- Schema fragment
<xs:complexType name="claim">
<xs:sequence>
<xs:element name="photo" ns1:expectedContentTypes="image/gif"
type="xs:base64Binary" minOccurs="0"
xmlns:ns1="http://www.w3.org/2005/05/xmlmime"/>
</xs:sequence>
</xs:complexType>
Collection Type
Collection type
包含有
array, list
以及泛型的
list
(如
List<Integer>
)等。有下列
3
种方法来把
collection type
映射到
web service schema data type
方法
1
:缺省处理
collection type
如果对于
collection type
(例如
List<Integer>
)不使用任何的
annotation
,那么缺省映射到
web service schema
为一个“
minOccurs=0
,
maxOccurs=unbounded
,
nillable=true
”的
datatype
。
Nillable
表示可以为
null
。
请注意:对于
collection type
,
web service schema
用
minOccurs=0
,
maxOccurs=unbounded
来表示!!如果
collection type
没有指定泛型,那么缺省为
String
对
collection type
缺省使用没有什么不妥,但由于
nillable=true
,所以
.NET
根据
web service schema
生成的
datatype
为
Nullable<int>[ ]
。
例子:
//-- Java code fragment
@XmlRootElement(name="po")
public PurchaseOrder {
public List<Integer> items;
}
//-- Schema fragment
<xs:element name="po" type="purchaseOrder">
<xs:complexType name="purchaseOrder">
<xs:sequence>
<xs:element name="items" type="xs:int" nillable="true"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
//-- .NET auto generated code from schema
partial class purchaseOrder {
private System.Nullable<int>[] itemsField;
public System.Nullable<int>[] items
{
get { return this.itemsField; }
set { this.itemsField = value; }
}
}
方法
2
:通过
@XmlElement annotation
定义成非
nillable
的
data type
//-- Java code fragment
@XmlRootElement(name="po")
public PurchaseOrder {
@XmlElement(nillable=false)
public List<Integer> items;
}
//-- Schema fragment
<xs:element name="po" type="purchaseOrder">
<xs:complexType name="purchaseOrder">
<xs:sequence>
<xs:element name="items" type="xs:int"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
...
// .NET auto generated code from schema
partial class purchaseOrder {
private int[] itemsField;
public int[] items
{
get { return this.itemsField; }
set { this.itemsField = value; }
}
}
方法
3
:通过
@XmlList annotation
定义成
web service schema
的
list data type
//-- Java code fragment
@XmlRootElement(name="po")
public PurchaseOrder {
@XmlList
public List<Integer> items;
}
//-- Schema fragment
<xs:element name="po" type="purchaseOrder">
<xs:complexType name="purchaseOrder">
<xs:element name="items" minOccurs="0">
<xs:simpleType>
<xs:list itemType="xs:int"/>
</xs:simpleType>
</xs:element>
</xs:complexType>
那么对于数组,只需要缺省处理就可以啦。
例子:
@WebService
public
class
HelloWS {
@WebMethod
public
int
[]
getMonths(){
return
null
;
}
}
上面的代码生成的
web service schema
的相关代码是:
<xs:complexType name='getMonthsResponse'>
<xs:sequence>
<xs:element maxOccurs='unbounded' minOccurs='0' name='return' type='xs:int'/>
</xs:sequence>
</xs:complexType>
可见
maxOccurs
属性同样可以用来表示数组!
************
一个需要很留意的问题
*************
如果你希望要用上面的方法
3
来设置你的
collection type
(例如
List<Integer>
),那么就一定不能够把
collection type
作为
web service method
的返回值,而应该用一个
class
来包装该
collection type
。
举个例子:
@WebService
public
class
HelloWS {
public
ArrayList<String>
getWords(){
return
null
;
}
}
上面的代码生成的
web service schema
的相关代码是:
<xs:complexType name='getWordsResponse'>
<xs:sequence>
<xs:element maxOccurs='unbounded' minOccurs='0' name='return' type='xs:string'/>
</xs:sequence>
</xs:complexType>
但你却无法生成使用方法
3
得到的代码:
<xs:complexType name='getWordsResponse'>
<xs:sequence>
<xs:element minOccurs='0' name='return' type='tns:words'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='words'>
<xs:sequence>
<xs:element minOccurs='0' name='words'>
<xs:simpleType>
<xs:list itemType='xs:string'/>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
解决办法就是定义一个
class
来包装该
collection type
变量:
@WebService
public
class
HelloWS {
public
Words
getWords(){
return
null
;
}
}
Words.java
public
class
Words
{
@XmlList
public ArrayList<String> words;
}
Enum Type
例子:
Country.java
public
enum
Country {
CHINA
,
ENGLAND
,
BRASIL
}
User.java
public
class
User {
public
Country
country
;
}
那么生成的
web service schema
相关代码为:
<xs:complexType name='user'>
<xs:sequence>
<xs:element minOccurs='0' name='country' type='tns:country'/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name='country'>
<xs:restriction base='xs:string'>
<xs:enumeration value='CHINA'/>
<xs:enumeration value='ENGLAND'/>
<xs:enumeration value='BRASIL'/>
</xs:restriction>
</xs:simpleType>