Поради та підказки по Web-сервісів: JAX-RPC проти JAX-WS, частина 2 (исходники), Різне, Програмування, статті

Введення


У той час як деякі аспекти JAX-WS 2.0 в JAX-RPC 1.1 просто зазнали еволюцію, інші змінилися самим революційним чином. Наприклад, JAX-WS не підтримує зіставлення даних між XML schema і Java, що є головною функцією в JAX-RPC 1.1. Замість цього в JAX-WS для такого зіставлення використовується інша JCP-технологія, JAXB 2.0 (Java Architecture for XML Binding, Java-архітектура для опису прив’язки для XML-даних). JAX-WS просто представляє модель виклику для Web-сервісів. Дану специфікацію більше не цікавлять bean-компоненти Java, що представляють дані програми; вона концентрується тільки на постачанні цих даних Web-сервісу призначення. У цій статті ми порівнюємо зіставлення в JAX-RPC 1.1 і JAXB 2.0.


Зіставлення XML schema – Java







 



JAX-RPC і JAXB
Чому з самого початку JAX-RPC не використовує JAXB? Відповідь криється в розбіжності даних розробок в часі. Перша версія JAX-RPC була закінчена раніше JAXB, тому розробники JAX-RPC вирішили не чекати і розробили свою функцію зіставлення імен.
 

Методи зіставлення імен XML іменах Java в JAX-RPC і JAX-WS/JAXB в основному аналогічні, хоча зіставлення примітивних типів в них злегка відрізняється. У таблиці 1 перераховані ці відмінності, вони можуть здатися суттєвими, а проте, якщо не вважати типів для дати / часу, це найменш використовувані примітивні типи даних XML.


Таблиця 1. Відмінності в зіставленні даних між JAX-RPC 1.1 і JAXB 2.0 для примітивних типів XML






































































Тип JAX-RPC 1.1 JAXB 2.0
xsd:anySimpleType java.lang.String java.lang.Object
xsd:duration java.lang.String javax.xml.datatype.Duration (новий тип)
xsd:dateTime java.util.Calendar javax.xml.datatype.XMLGregorianCalendar (новий тип)
xsd:time java.util.Calendar javax.xml.datatype.XMLGregorianCalendar
xsd:date java.util.Calendar javax.xml.datatype.XMLGregorianCalendar
xsd:gYearMonth java.lang.String javax.xml.datatype.XMLGregorianCalendar
xsd:gYear java.lang.String javax.xml.datatype.XMLGregorianCalendar
xsd:gMonthDay java.lang.String javax.xml.datatype.XMLGregorianCalendar
xsd:gMonth java.lang.String javax.xml.datatype.XMLGregorianCalendar
xsd:gDay java.lang.String javax.xml.datatype.XMLGregorianCalendar
xsd:anyURI java.net.URI java.lang.String
xsd:NMTOKENS java.lang.String[] java.util.List<java.lang.String>
xsd:IDREF java.lang.String java.lang.Object
xsd:IDREFS java.lang.String[] java.util.List<java.lang.Object>
xsd:ENTITY не підтримується java.lang.String
xsd:ENTITIES не підтримується java.util.List<java.lang.String>

Аспекти “pure Java” для зіставлень примітивних типів даних майже не відрізняються в JAX-RPC і JAXB, але зіставлення в JAXB, крім цього, використовують нову функцію анотацій Java. У лістингах з 1 по 3 наводиться кілька прикладів зіставлень примітивних типів даних.


Лістинг 1. Елементи й атрибути XML-типу complexType





<xsd:sequence>
<xsd:element name=”intField” type=”xsd:int”/>
<xsd:element name=”intMinField” type=”xsd:int” minOccurs=”0″/>
<xsd:element name=”intNilField” type=”xsd:int” nillable=”true”/>
<xsd:element name=”stringField” type=”xsd:string”/>
<xsd:element name=”stringMinField” type=”xsd:string” minOccurs=”0″/>
<xsd:element name=”stringNilField” type=”xsd:string” nillable=”true”/>
</xsd:sequence>
<xsd:attribute name=”intAttr” type=”xsd:int”/>
<xsd:attribute name=”intAttrReq” type=”xsd:int” use=”required”/>

Лістинг 2. Зіставлення у властивостях bean-компонентів Java по JAX-RPC 1.1





private int intField;
private Integer intMinField;
private Integer intNilField;
private String stringField;
private String stringMinField;
private String stringNilField;
private Integer intAtt;
private int intAttReq;

Лістинг 3. Зіставлення у властивостях bean-компонентів Java по JAXB 2.0





protected int intField;
protected Integer intMinField;
@XmlElement(required = true, type = Integer.class, nillable = true)
protected Integer intNilField;
@XmlElement(required = true)
protected String stringField;
protected String stringMinField;
@XmlElement(required = true, nillable = true)
protected String stringNilField;
@XmlAttribute
protected Integer intAtt;
@XmlAttribute(required = true)
protected int intAttReq;

В bean-компоненті, створеному в JAX-RPC 1.1, ви не зможете визначити різницю між:


Але тепер це можна зробити завдяки тому, що JAXB використовує нові анотації Java. Анотації @XmlElement і @XmlAttribute мають декілька параметрів. Нижче перераховані ті з них, які мають відношення до теми цієї статті:



Зіставлення масивів


Зіставлення масивів XML в Java в моделях JAX-RPC і JAXB різному, тому що JAXB використовує нову родову функцію Java, як показано в лістингу 4-6.


Лістинг 4. XML-масив





<xsd:element name=”intArrayField” type=”xsd:int” minOccurs=”0″ maxOccurs=”unbounded”/>

Лістинг 5. Зіставлення у властивостях Java Bean по JAX-RPC 1.1





private int[] intArrayField;
public int[] getIntArrayField() {..}
public void setIntArrayField(int[] intArrayField) {..}
public int getIntArrayField(int i) {..}
public void setIntArrayField(int i, int value) {..}

Лістинг 6. Зіставлення у властивостях Java Bean по JAXB 2.0





@XmlElement(type = Integer.class)
protected List<Integer> intArrayField;
public List<Integer> getIntArrayField() {..}

Зверніть увагу на відмінності в методах доступу. Зіставлення в JAX-RPC слід строгому визначенню методів доступу до масиву bean-компонента Java. Зіставлення в JAXB не відображає дані в масив, тому воно дещо відрізняється. Метод getIntArrayField повертає в активний список не тільки моментальний знімок, але і посилання. Отже, будь-яка зміна, яку ви внесете в повертається список, буде представлено в рамках властивості. Саме тому для властивостей масиву не існує метод set.


Відображення складових типів


Зіставлення complexType майже не відрізняється в JAX-RPC і JAXB, за винятком полів з атрибутом “private” у JAX-RPC і “protected” в JAXB, а зіставлення JAXB додає анотації, що описують порядок сортування в полі. У лістингах 7-9 наведено приклад і порівняння цих двох зіставлень.


Лістинг 7. XML-схема: тип complexType





<xsd:element name=”Phone” type=”tns:Phone”/>
<xsd:complexType name=”Phone”>
<xsd:sequence>
<xsd:element name=”areaCode” type=”xsd:string”/>
<xsd:element name=”exchange” type=”xsd:string”/>
<xsd:element name=”number” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>

Лістинг 8. Зіставлення complexType в JAX-RPC 1.1





public class Phone {
private String areaCode;
private String exchange;
private String number;
..
}

Лістинг 9. Зіставлення complexType в JAXB 2.0





@XmlType(name = “Phone”, propOrder = {
“areaCode”,
“exchange”,
“number”
})
public class Phone {
@XmlElement(required = true)
protected String areaCode;
@XmlElement(required = true)
protected String exchange;
@XmlElement(required = true)
protected String number;
..
}

Зверніть увагу на те, що в схемі з лістингу 7 використовується xsd:sequence. Якби замість цього стояло xsd:all, То коментар propOrder був би порожнім: @XmlType(name = “Phone”, propOrder = {}).


Новий клас ObjectFactory


JAXB генерує один файл, який відсутній в JAX-RPC: ObjectFactory. Кожен каталог, що містить bean-компоненти Java, буде включати один файл ObjectFactory. Для кожного типу, визначеного в просторі імен, відповідному цій схемі, клас ObjectFactory матиме метод create. Для кожного елемента клас ObjectFactory матиме метод create element, який повертає примірник javax.xml.bind.JAXBElement<Type>. Наприклад, в лістингу 10 показаний клас ObjectFactory, Згенерований для схеми Phone з лістингу 7 з методом, що повертає примірник Phone, І методом, що повертає примірник JAXBElement<Phone>. Як і раніше допускається створення примірників bean-компонентів в цьому каталозі, але краще скористатися фабрикою.


Лістинг 10. ObjectFactory JAXB 2.0 для Phone





import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.namespace.QName;
public class ObjectFactory {
private final static QName _Phone_QNAME = new QName
(“urn:types.MyServiceSample.ibm.com”, “Phone”);
public ObjectFactory() {..}
public Phone createPhone() {..}
@XmlElementDecl(namespace = “urn:types.MyServiceSample.ibm.com”, name = “Phone”)
public JAXBElement<Phone> createPhone(Phone value) {..}
}

Зіставлення Java – XML ​​schema


Завдяки раціональної вставці описаних вище нових визначених у JAXB-анотацій, можна точно зіставити Java і XML, особливо в напрямку, зворотному зіставленню XML-Java, про який ми говорили. А як бути з Java без анотацій?


Зіставлення імен в Java іменам в XML по специфікаціям JAX-RPC і JAXB, в основному, аналогічні. Тобто, примітивні типи Java зіставляються таким же типам XML schema, незалежно від того, використовується Чи зіставлення за моделлю JAX-RPC або за моделлю JAXB. Специфікація JAX-RPC визначає невеликий набір стандартних класів Java, зіставляються XML. Зіставлення всіх класів, окрім одного, в JAXB практично однаково, але при цьому JAXB додає ще кілька порівнянних класів, як показано в таблиці 2.


Таблиця 2. Відмінності в зіставленні даних між JAX-RPC 1.1 і JAXB 2.0 для стандартних класів Java






























































Тип JAX-RPC 1.1 JAXB 2.0
java.lang.String xsd:string xsd:string
java.math.BigInteger xsd:integer xsd:integer
java.math.BigDecimal xsd:decimal xsd:decimal
java.util.Calendar xsd:dateTime xsd:dateTime
java.util.Date xsd:dateTime xsd:dateTime
javax.xml.namespace.QName xsd:QName xsd:QName
java.net.URI xsd:anyURI xsd:string
javax.xml.datatype.XMLGregorianCalendar немає xsd:anySimpleType
javax.xml.datatype.Duration немає xsd:duration
java.lang.Object немає1  xsd:anyType
java.awt.Image немає2  xsd:base64Binary
javax.activation.DataHandler немає2  xsd:base64Binary
javax.xml.transform.Source немає2  xsd:base64Binary
java.util.UUID немає xsd:string

Примітки до таблиці 2:
1. Деякі виробники зіставляють клас java.lang.Object класу xsd: anyType.
2. В JAX-RPC цей клас зіставляється типу mime binding – тип XML не визначений.


Висновок


Ми порівняли зіставлення в JAX-RPC 1.1 і JAXB 2.0. В цілому, вони аналогічні, за невеликими винятками:

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*