420 likes | 776 Views
CERN – European Organization for Nuclear Research. ИСПОЛЬЗОВАНИЕ ТЕХНОЛОГИИ JAXB ПРИ РАЗРАБОТКЕ XML ПРИЛОЖЕНИЙ. IT Department – e -Business Section. Afonin Alexey, Derek Mathieson e-Business section, IT department CERN – Geneva, Switzerland. JAXB. JAXB:
E N D
CERN – European Organization for Nuclear Research ИСПОЛЬЗОВАНИЕ ТЕХНОЛОГИИ JAXBПРИ РАЗРАБОТКЕ XML ПРИЛОЖЕНИЙ IT Department – e-Business Section Afonin Alexey, Derek Mathieson e-Business section,IT department CERN – Geneva, Switzerland
JAXB JAXB: • The Java Architecture for XML Binding • Спецификация принята 8 Января 2003 года http://java.sun.com/xml/downloads/jaxb.html Доступные реализации: • SUN, является частью Java Web Services Developer Pack http://java.sun.com/xml/downloads/jaxb.html • Apache JAXME http://ws.apache.org/jaxme/
Пример: XML <orders-list> <order> <number>1001</number> <date>2005-01-01</date> <description>First Order</description> <amount>10</amount> </order> <order> <number>1002</number> <date>2005-01-02</date> <description>Second Order</description> <amount>20.2</amount> </order> </orders-list>
Пример: XML Schema <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsd:element name="orders-list"> <xsd:complexType> <xsd:sequence> <xsd:element ref="order" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="order"> <xsd:complexType> <xsd:sequence> <xsd:element name="number" type="xsd:long"/> <xsd:element name="date" type="xsd:date"/> <xsd:element name="description" type="xsd:string"/> <xsd:element name="amount" type="xsd:double"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>
Пример: Генерация Java классов Из командной строки: %jwsdp.home%\jaxb\bin\xjc.bat -p generated -d src simple-order.xsd Из скрипта Ant: <project basedir="." default="generate"> <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask“ classpathref="classpath“> <target name="generate"> <xjcschema="simple-order.xsd" target="src" package="generated"/> </target> </project>
Пример: сгенерированные Java классы OrdersListType.java public interface OrdersListType { java.util.List getOrder(); } OrderType.java public interface OrderType { doublegetAmount(); void setAmount(double value); java.lang.String getDescription(); void setDescription(java.lang.String value); java.util.Calendar getDate(); void setDate(java.util.Calendar value); long getNumber(); void setNumber(long value); }
Пример: работа с JAXB JAXBContext jaxbCtx = JAXBContext.newInstance("generated"); Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller(); OrdersListType orders = (OrdersListType)unmarshaller.unmarshal( new File("simple-order.xml")); List ordersList = orders.getOrder(); for (int i = 0; i < ordersList.size(); i++) { OrderType order = (OrderType)ordersList.get(i); System.out.println("Number = " + order.getNumber() + ", amount = " + order.getAmount()); } ... Чтение из XML файла
Пример: работа с JAXB ... ObjectFactory objectFactory = new ObjectFactory(); Order newOrder = objectFactory.createOrder(); newOrder.setNumber(2006); newOrder.setDate(Calendar.getInstance()); newOrder.setDescription("New Order"); newOrder.setAmount(100); orders.getOrder().add(newOrder); Marshaller marshaller = jaxbCtx.createMarshaller(); marshaller.marshal(orders, new FileOutputStream(new File("simple-order.xml"))); Изменение XML файла
Пакет Связывания Основные операции: • маршаллинг (marshalling) • демаршаллинг (unmarshalling) • проверка(validation) Класс javax.xml.bind.JAXBContext - "точка входа" в JAXB API public abstract class JAXBContext { static JAXBContext newInstance(String contextPath) static JAXBContext newInstance(String contextPath, ClassLoader contextPathCL) abstract Unmarshaller createUnmarshaller(); abstract Marshaller createMarshaller(); abstract Validator createValidator(); }
Проверка XML документа JAXB предоставляет три варианта проверки XML документа: • во время демаршаллинга (unmarshall-time validation) • по требованию (on-demand validation) • "на лету" (fail-fast validation) Validatorпозволяет проверять объектное представление документа public interface Validator { ValidationEventHandler getEventHandler() void setEventHandler(ValidationEventHandlerhandler) boolean validate(java.lang.Object subrootObject) boolean validateRoot(java.lang.Object rootObject) }
Демаршаллинг public interface Unmarshaller { boolean isValidating() throws JAXBException; void setValidating(boolean b) throws JAXBException; ValidationEventHandler getEventHandler() throws JAXBException; void setEventHandler(ValidationEventHandler handler) throws JAXBException; Object unmarshal(File file) throws JAXBException; Object unmarshal(InputStreamis)throws JAXBException; Object unmarshal(URL url) throws JAXBException; Object unmarshal(Source source) throws JAXBException; Object unmarshal(Node node) throws JAXBException; Object unmarshal(InputSourceis) throws JAXBException; } Unmarshaller читает XML документ, выполняет его проверку и строит объектную модель
Маршаллинг Marshaller сохраняет объектную модель в XML документ public interface Marshaller { ValidationEventHandler getEventHandler() throws JAXBException; void setEventHandler(ValidationEventHandler handler) throws JAXBException; void marshal(Object o, OutputStreamos) throws JAXBException; void marshal(Object o, Writer writer) throws JAXBException; void marshal(Object o, Result result) throws JAXBException; void marshal(Object o, Node node) throws JAXBException; void marshal(Object o, ContentHandlerch) throws JAXBException; Node getNode(Object o) throws JAXBException; Object getProperty(String s) throws PropertyException; void setProperty(String s, Object o) throws PropertyException; String JAXB_ENCODING = "jaxb.encoding"; String JAXB_FORMATTED_OUTPUT = "jaxb.formatted.output"; }
Связывание XML схемы и Java Представления Binding XML Schema to Java Classes
Связывание составных типов данных Составной тип XML схемы Java интерфейс <xsd:complexType name="personType"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="departmentId" type="xsd:long"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:long"/> </xsd:complexType> public interface PersonType { long getDepartmentId(); void setDepartmentId(long value); java.lang.String getName(); void setName(java.lang.String value); long getId(); void setId(long value); }
Свойства (Properties) Вложенные компоненты XML схемы Java свойства Простое свойство (Simple Property) <xsd:element name="name" type="xsd:string"/> java.lang.String getName(); void setName(java.lang.String value); Группа свойств (Collection Property) <xsd:element name="item" type="xsd:string"maxOccurs="unbounded"/> java.util.List getItem();
Перечисление (Type Safe Enumeration) Производный атомарный тип данных с ограничением типа «перечисление» Перечисление (Type Safe Enumeration) <xsd:simpleType name="countryType"> <xsd:restriction base="xsd:NCName"> <xsd:enumeration value="FRANCE"/> <xsd:enumeration value="SWITZERLAND"/> </xsd:restriction> </xsd:simpleType> public class CountryType { private final String value; protected CountryType(String v) { value = v; } public final static CountryType FRANCE = new CountryType("FRANCE"); public final static CountryType SWITZERLAND = new generated.CountryType("SWITZERLAND"); ... }
Связывание встроенных типов данных Таблица соответствия встроенных типов (Simple Built-in Types)
Наследование Наследование XML типов через ограничение (restriction) или расширение (extension) Java наследование <xsd:complexType name="Address"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="street" type="xsd:string"/> <xsd:element name="city" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="USAddress"> <xsd:complexContent> <xsd:extension base="Address"> <xsd:sequence> <xsd:element name="state" type="xsd:string"/> <xsd:element name="zip" type="xsd:integer"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType>
Наследование Наследование XML типов через ограничение (restriction) или расширение (extension) Java наследование public interface Address { java.lang.String getCity(); void setCity(java.lang.String value); java.lang.String getStreet(); void setStreet(java.lang.String value); java.lang.String getName(); void setName(java.lang.String value); } public interface USAddressextendsAddress { java.lang.String getState(); void setState(java.lang.String value); long getZip(); void setZip(long value); }
Переопределение Связывания Customizing JAXB Bindings
Зачем Переопределять? Стандартное связывания (Default Binding) Переопределение связывания: • создание документации (Javadoc) • изменение правил именования • разрешить конфликтов имен • определить имена для констант перечислений • определять свои типы данных для атрибутов • переопределять связывание встроенных типов • переопределять маршаллинг / демаршаллинг для пользовательских типов данных
Встроенное и Внешнее Переопределение Встроенное переопределение – внутри XML схемы <xs:annotation> <xs:appinfo> <!-- binding declarations --> </xs:appinfo> </xs:annotation> Внешнее переопределение – отдельный файл <jxb:bindings schemaLocation = "xs:anyURI"> <jxb:bindings node = "xs:string">* <!-- binding declarations --> <jxb:bindings> </jxb:bindings>
Использование Внешнего Переопределения Командная строка xjc –b <file> <schema> Скрипт Ant <xjc schema="simple-order.xsd" target="src" binding="cxml-binding.xjb" package="generated"/>
Глобальные Переопределения <globalBindings> [ collectionType = "collectionType" ] [ generateIsSetMethod= "true" | "false" | "1" | "0" ] [ enableFailFastCheck = "true" | "false" | "1" | "0" ] [ underscoreBinding = "asWordSeparator" | "asCharInWord" ] [ typesafeEnumBase = "typesafeEnumBase" ] [ <javaType> ... </javaType> ]* </globalBindings>
Переопределения Уровня Схемы <schemaBindings> [ <package> package </package> ] [ <nameXmlTransform> ... </nameXmlTransform> ]* </schemaBindings> <package [ name = "packageName" ] [ <javadoc> ... </javadoc> ] </package> <nameXmlTransform> [ <typeName [ suffix="suffix" ] [ prefix="prefix" ] /> ] [ <elementName [ suffix="suffix" ] [ prefix="prefix" ] /> ] </nameXmlTransform>
Переопределения Типов Данных и Компонент <class [ name = "className"] [ implClass= "implClass" ] > [ <javadoc> ... </javadoc> ] </class> Связывание Классов Связывание Свойств <property[ name = "propertyName"] [ collectionType = "propertyCollectionType" ] [ generateIsSetMethod = "true" | "false" | "1" | "0" ] [ enableFailFastCheck ="true" | "false" | "1" | "0" ] [ <baseType> ... </baseType> ] [ <javadoc> ... </javadoc> ] </property> <baseType> <javaType> ... </javaType> </baseType>
Переопределения Типов Данных и Компонент <javaType name= "javaType" [ xmlType= "xmlType" ] [ parseMethod= "parseMethod" ] [ printMethod= "printMethod" ]/> Преобразование типов данных Java XML
Пример Настройки Связывания <jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0"> <jxb:bindings schemaLocation="cxml.xsd"node="/xs:schema" > <jxb:schemaBindings> <jxb:package name="cern.edh.cxml.objects"/> <jxb:nameXmlTransform> <jxb:typeName suffix="Type"/> </jxb:nameXmlTransform> </jxb:schemaBindings> ...
Пример Настройки Связывания <jxb:bindings node="/xs:schema" schemaLocation="cxml.xsd"> ... <jxb:bindings node="//xs:simpleType[@name='datetime.tz']"> <jxb:javaType name="java.util.Date" parseMethod="cern.edh.cxml.DateConverter.parseDateTz" printMethod="cern.edh.cxml.DateConverter.printDateTz"/> </jxb:bindings> <jxb:bindings node="//xs:simpleType[@name='deploymentModeValue']"> <jxb:typesafeEnumClass/> </jxb:bindings> </jxb:bindings> </jxb:bindings>
Пример: Разрешение Конфликтов Имен <jxb:nameXmlTransform> <jxb:typeName suffix="Type"/> </jxb:nameXmlTransform> <xs:element name="Money" type="Money"/> <xs:complexType name="Money"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="currency" type="xs:string"/> <xs:attribute name="alternateAmount" type="xs:double"/> <xs:attribute name="alternateCurrency" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> cern.edh.cxml.objects.Money cern.edh.cxml.objects.MoneyType
Пример: Преобразование Типов Данных <jxb:bindings node="//xs:simpleType[@name='datetime.tz']"> <jxb:javaType name="java.util.Date" parseMethod="cern.edh.cxml.DateConverter.parseDateTz" printMethod="cern.edh.cxml.DateConverter.printDateTz"/> </jxb:bindings> package cern.edh.cxml; public class DateConverter { public static java.util.Date parseDateTz(String lexicalDate) throws ParseException {...} public static String printDateTz(java.util.Date date) {...} }
Пример: Преобразование Типов Данных <xs:simpleType name="datetime.tz"> <xs:restriction base="xs:string"/> </xs:simpleType> <xs:element name="cXML"> ... <xs:attribute name="timestamp" type="datetime.tz"/> <xs:element name="cXML"> public interface CXMLType { ... java.util.Date getTimestamp(); void setTimestamp(java.util.Date value); } <cXML timestamp="2000-08-03T08:49:09+07:00"> ... </cXML>
Пример: Перечисление <jxb:bindings node="//xs:simpleType[@name='deploymentModeValue']"> <jxb:typesafeEnumClass/> </jxb:bindings> <xs:simpleType name="deploymentModeValue"> <xs:restriction base="xs:sting"> <xs:enumeration value="production"/> <xs:enumeration value="test"/> </xs:restriction> </xs:simpleType> public class DeploymentModeValue { public final static DeploymentModeValue PRODUCTION = new DeploymentModeValue(_PRODUCTION); public final static DeploymentModeValue TEST = new DeploymentModeValue(_TEST); ... }
JAXB vs. JAXP JAXB следует использовать когда нужно: • Создавать объектные представления данных XML • Обрабатывать только верные данные • Преобразовывать данные к различным типам JAXP следует использовать когда нужно: • Обрабатывать документы, построенные на различных DTD • Обрабатывать документы, которые не обязательно являются правильными • Применять XSLT преобразования • Обрабатывать лишь отдельные части XML документа
Использование JAXB Система Электронного Документооборота (EDH) Приложение электронной коммерции B2B: • стандарт cXML • ~ 100 интерфейсов объектной модели • ~ 100 классов реализации
XML элемент XML элемент Java интерфейс элемента Тип элемента объявлен составным (Complex type definition): <xsd:complexType name="personType"> ... <!-– вложенные элементы --> </xsd:complexType> <xsd:element name="person" type="personType"/> public interface PersonType { ...<!–свойства для вложенных элементов --> } public interface Person extends javax.xml.bind.Element, PersonType { }
XML элемент XML элемент Java интерфейс элемента Тип элемента объявлен простым (Simple type definition): <xsd:element name="name" type="xsd:string"/> public interface Name extends javax.xml.bind.Element { java.lang.String getValue(); void setValue(java.lang.String value); }
Компонент Тип Данных Схема Глобальные Переопределения Уровни Действия Переопределения Каждый следующий уровень по отношению к предыдущему: • наследует • переопределяет