Как сгенерировать класс Java, который реализует интерфейс Serializable из xsd с использованием JAXB?

Я хотел бы ввести кеширование в существующий проект Spring, который использует JAXB для предоставления WebServices. Кеширование будет производиться на уровне конечных точек. Для этого классы, созданные из XSD с использованием JAXB, должны реализовать интерфейс Serializable и переопределить метод toString() Object.

Как настроить инструмент xjc с помощью XSD для создания источника с необходимыми свойствами?


person Boris Pavlović    schedule 03.10.2009    source источник
comment
Одна из возможностей - использовать плагины JAXB (jaxb2-commons.dev.java.net)   -  person dma_k    schedule 03.11.2010
comment
@dma_k и как именно это делается с помощью jaxb2-commons?   -  person Bozho    schedule 25.01.2011


Ответы (6)


Сериализуемый

Используйте xjc:serializable в файле пользовательских привязок, чтобы добавить java.io.Serializable интерфейс к вашим классам вместе с serialVersionUID:

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
            xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
            xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
            xsi:schemaLocation="
http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
  <globalBindings>
    <serializable uid="1" />
  </globalBindings>
</bindings> 

нанизывать()

Используйте суперкласс (см. xjc:superClass), от которого будут унаследованы все ваши связанные классы. Этот класс не будет сгенерирован xjc, поэтому вы можете создавать его по своему усмотрению (здесь с реализацией toString()):

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
                xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
                xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                xsi:schemaLocation="
http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
    version="2.1">
    <globalBindings>
        <serializable uid="1" />
        <xjc:superClass name="the.package.to.my.XmlSuperClass" />
    </globalBindings>
</bindings>
person Pascal Thivent    schedule 03.10.2009
comment
Спасибо за отличный ответ. Вы бы использовали построитель toString в Apache Commons lang ToStringBuilder на основе отражения? - person Boris Pavlović; 05.10.2009
comment
Да, в вашем случае это хороший выбор (на самом деле, я не думаю, что у вас есть много других вариантов). - person Pascal Thivent; 05.10.2009
comment
На самом деле есть: Pojomatic (pojomatic.sourceforge.net/pojomatic/index.html ) - person Boris Pavlović; 29.04.2010
comment
@Pascal: Я считаю, что в этом примере нужно сказать <xjc:serializable ...>, поскольку пространство имен по умолчанию отличается от xjc. - person dma_k; 04.11.2010
comment
После применения <xjc:superClass...> у меня осталось @XmlValue is not allowed on a class that derives another class. Решение: добавьте аннотацию @javax.xml.bind.annotation.XmlTransient к базовому классу (см. Здесь: sites.google.com/site/codingkb/java-2/jaxb/jaxb-4) - person dma_k; 04.11.2010
comment
Есть ли способ сообщить xjc, что только некоторые классы расширяют XMLSuperClass? - person Chobicus; 08.08.2012
comment
Для получения дополнительной информации о том, как использовать файл привязок в maven, см. stackoverflow.com/a/903629/496166. - person kevinmrohr; 29.10.2012
comment
Мне пришлось поместить ответ в файл bindings.xml и добавить jaxb: перед тегами (например: jaxb:bindings) и xjc:serializable и запустить это в консоли: xjc -extension -d out -b bindings.xml yourSchema.xsd - person Shehaaz; 07.03.2016
comment
Вам не нужен extensionBindingPrefixes="xjc"? - person OrangeDog; 03.01.2017

Это сработало для меня:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:version="2.1">
    <jaxb:globalBindings>
        <xjc:serializable uid="1337"/>
    </jaxb:globalBindings>
</jaxb:bindings>
person vikingsteve    schedule 22.11.2013

Другой способ создания toString() метода - подключаемые модули для базовых функций JAXB2. Этот способ выглядит лучше, потому что не использует отражение. Пример того, как это сделать с maven, ниже.

<build>
    <plugins>
        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.8.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaDirectory>
                    ${project.basedir}/src/main/resources
                </schemaDirectory>
                <generateDirectory>
                    ${project.basedir}/src/main/java
                </generateDirectory>
                <extension>true</extension>
                <args>
                    <arg>-XtoString</arg>
                </args>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics</artifactId>
                        <version>0.6.4</version>
                    </plugin>
                </plugins>
            </configuration>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.jvnet.jaxb2_commons</groupId>
        <artifactId>jaxb2-basics-runtime</artifactId>
        <version>0.6.4</version>
    </dependency>
</dependencies>

В результате вы получите такой код.

public String toString() {
    final ToStringStrategy strategy = JAXBToStringStrategy.INSTANCE;
    final StringBuilder buffer = new StringBuilder();
    append(null, buffer, strategy);
    return buffer.toString();
}

public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
    strategy.appendStart(locator, this, buffer);
    appendFields(locator, buffer, strategy);
    strategy.appendEnd(locator, this, buffer);
    return buffer;
}

public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
    {
        String theName;
        theName = this.getName();
        strategy.appendField(locator, this, "name", buffer, theName);
    }
    {
        String theBank;
        theBank = this.getBank();
        strategy.appendField(locator, this, "bank", buffer, theBank);
    }
    return buffer;
}
person artspb    schedule 09.12.2012

Я использую этот код, и он работает на меня

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:version="2.1">
    <jaxb:globalBindings>
        <xjc:serializable uid="1"/><!--If you Forgot this line your class did not be serializable--!>
    </jaxb:globalBindings>
</jaxb:bindings>
person BERGUIGA Mohamed Amine    schedule 24.09.2014

Чтобы получить интерфейс Serializable, добавьте в xsd-файл следующую информацию о привязке:

<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"> <xs:annotation> <xs:appinfo> <jaxb:globalBindings optionalProperty="primitive"> <jaxb:serializable/> </jaxb:globalBindings> </xs:appinfo> </xs:annotation> <xs:element name="myXsdElement"> ..... </xs:element> </xs:schema>

person Gio    schedule 01.09.2016

А вот пример с использованием CXF 3.1.10. Не забудьте включить группу компиляции: 'org.apache.cxf.xjc-utils', имя: 'cxf-xjc-runtime', версия: '3.1.0'

<jxb:bindings 
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">

<jxb:bindings schemaLocation="META-INF/wsdl/xsd2.xsd">

        <jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                <jxb:serializable uid="1"/>
              </jxb:globalBindings>
person Jacques Koorts    schedule 28.02.2017