Как использовать ObjectFactory, сгенерированный Jaxb?

Я использую Jaxb для создания классов Java. В моей схеме определен следующий элемент:

<xs:complexType name="AutomobileType" abstract="true">
    <xs:sequence>
        <xs:element name="Color" type="core:ColorName"/>
        <xs:element name="Weight" type="core:PoundsWeightType"/>
        <xs:element name="Fuel" type="Fuel"/>
        <xs:element name="NumDoors" type="xs:nonNegativeInteger"/>
        <xs:element name="NumCylinders">
            <xs:simpleType>
                <xs:restriction base="xs:int">
                    <xs:minInclusive value="1"/>
                    <xs:maxInclusive value="12"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:element>
    </xs:sequence>
</xs:complexType>    
<xs:element name="Automobile" type="AutomobileType"/>

Как видите, у меня есть один элемент с именем Автомобиль.

Jaxb создает классы и ObjectFactory, которые я использую для создания экземпляров Automobile. Меня смущает следующий метод создания экземпляра Automobile:

public JAXBElement<AutomobileType> createAutomobile(AutomobileType value)

Почему у метода createAutomobile есть аргумент? Как использовать этот метод?

Я пробовал следующее:

ObjectFactory objectFactory = new ObjectFactory();
objectFactory.createAutomobile(new Automobile());

но это не компилируется, потому что класс Automobile является абстрактным, и поэтому я не могу создать экземпляр.


person Jan Tacci    schedule 19.01.2013    source источник
comment
Я изменил класс «Автомобиль» на «Не быть абстрактным», и теперь все работает нормально. Однако, когда я пытаюсь маршалировать экземпляр Automobile, я получаю следующую ошибку: невозможно маршалировать тип com.cookmv.dealership.vehicles.schemas.automobile.AutomobileType как элемент, потому что в нем отсутствует аннотация @XmlRootElement]   -  person Jan Tacci    schedule 19.01.2013


Ответы (1)


Есть еще метод:

 public AutomobileType createAutomobileType();

В JAXB конструкция xsd:complexType "AutomobileType" сопоставляет одноименный класс. Предполагается, что это структура данных, эквивалентная этому типу схемы XML.

JAXBElement‹> — это (параметризованный) тип-оболочка, который связывает объект java, имя и пространство имен элемента, и поэтому его конструктор принимает объект AutomobileType в качестве параметра в конструкторе в дополнение к пространству имен и имени элемента. Сгенерированный ObjectFactory "createAutomobile(..)" - это просто удобный метод для переноса этого конструктора, жестко кодирующий ваше пространство имен и имя элемента из вашей XML-схемы.

Хотя эта дихотомия поначалу не совсем очевидна, учтите, что у вас может быть другой элемент с другим именем.

They would be structurally equivalent, but the element name would be different. You would have another ObjectFactory method "createMotorcycle(...)".

Вы можете создать безымянный объект carsType для построения содержимого элемента xml, а затем сообщить JAXB, в каком именно элементе XML он должен быть представлен.

Я не могу рекомендовать достаточно прочитать документацию JAXB по этой теме.

person Patrice M.    schedule 19.01.2013
comment
Мой ObjectFactory имеет только 1 метод. У него нет метода без аргументов createAutomobileType(). - person Jan Tacci; 19.01.2013
comment
Это может иметь какое-то отношение к abstract=true в комплексном типе. Бьюсь об заклад, если вы установите для него значение false, вы получите это. У вас случайно не определены конкретные подтипы? Если это так, у вас будет соответствующий метод create в ObjectFactory, а тип JAXB также будет подтипом абстрактного класса AutomobileType, что означает, что вы можете передать экземпляр методу createAutomobile(AutomobileType). JAXB довольно точно отображает семантику этих двух конструкций. - person Patrice M.; 19.01.2013