JAXB 2.0处理特殊的data type

来源:互联网 发布:大连大学校园网络 编辑:程序博客网 时间:2024/06/08 19:33
 
http://docs.sun.com/app/docs/doc/820-1072/ahigx?l=zh_TW&a=view 对一些特殊的data typejavaweb service xml之间的绑定和映射进行了详细的讲解。下面只是对其中一些部分进行翻译。
 
对那些基本类型(如int, long, double, string),不需要添加任何的annotation就可以进行把java data type映射到web service schema data type即使你是用自定义的class来包装基本类型(象下面例子中的user class
 
举个例子:
User class
publicclass User {
    public Long id;
    public String name;
    publicintage;
}
 
@WebService
publicclass HelloWS {
    @WebMethod
    public String getHello(String name){
       return"hello " + name;
    }
    @WebMethod
    public User getUser(long id){
       returnnull;
    }  
}
 
上面的代码生成的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
10Enum type
 
这些datatypeJAX-WS 2.0对它映射转换成web service schema data type有时必须要借助JAXBannotation!!(因此,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=unboundednillable=true”的datatype
 
Nillable表示可以为null
 
请注意:对于collection typeweb service schemaminOccurs=0 maxOccurs=unbounded来表示!!如果collection type没有指定泛型,那么缺省为String
 
collection type缺省使用没有什么不妥,但由于nillable=true,所以.NET根据web service schema生成的datatypeNullable<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定义成非nillabledata 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 schemalist 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
publicclass HelloWS {
    @WebMethod
    publicint[] getMonths(){
       returnnull;
    }
}
 
上面的代码生成的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
publicclass HelloWS {
    publicArrayList<String> getWords(){
       returnnull;
    }
}
 
上面的代码生成的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
publicclass HelloWS {
    publicWords getWords(){
       returnnull;
    }
}
 
Words.java
publicclassWords {
    @XmlList
    public ArrayList<String> words;
}
 
 
Enum Type
例子:
Country.java
publicenum Country {
    CHINA, ENGLAND, BRASIL
}
 
User.java
publicclass 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>
 
 
原创粉丝点击