Как создать класс Java, который реализует интерфейс Serializable из xsd с помощью JAXB?
Я хотел бы ввести кэширование в существующий проект Spring, который использует JAXB для публикации WebServices. Кэширование будет выполняться на уровне конечных точек. Для того, чтобы эти классы, созданные из XSD, используя JAXB, необходимо реализовать интерфейс Serializable
и переопределить метод Object
toString()
.
Как проинструктировать инструмент xjc с помощью XSD для генерации источника с необходимыми свойствами?
Ответы
Ответ 1
Сериализуемый
Используйте 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>
ToString()
Используйте суперкласс (см. 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>
Ответ 2
Это сработало для меня:
<?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>
Надеюсь, что это поможет.
Ответ 3
Другой способ генерации toString()
метода - JAXB2 Basics Plugins. Этот способ выглядит лучше, потому что не использует отражение. Пример, как это сделать с 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;
}
Ответ 4
Я использую этот код и работаю для меня
<?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>
Ответ 5
чтобы получить интерфейс 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>
Ответ 6
И вот пример с использованием 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>