#java #enums #jaxb #xsd #tostring
#java #перечисления #jaxb #xsd #tostring
Вопрос:
Фоновая проблема заключается в том, что когда мы размышляем о Enum
классе, сгенерированном JAXB, toString()
вызывается класс, который без @override
of toString()
вернет .name()
вместо .value()
. Итак, я хотел бы внедрить свой собственный toString()
.
Я не могу внедрить код в класс, созданный Enum
JAXB. Хотя я могу вводить код на верхнем уровне complexType
, но не в встроенный Enum
класс.
Вот раздел рассматриваемого XSD, показанный ниже (я пробовал абсолютный и относительный):
<jxb:bindings node="/xs:schema/xs:complexType[@name='QueryPgm']/xs:sequence/xs:element[@name='STATUS']/xs:simpleType">
Я использую эти аргументы:
"-verbose -Xinject-code -extension"
Ошибок не появляется, и вывод:
разбор схемы... компиляция схемы... [ИНФОРМАЦИЯ] генерация кода неизвестное местоположение com/ibm/query /pgm/ObjectFactory com/ibm/query/pgm/QueryPgm com /ibm/query/pgm/package-info
Вот раздел рассматриваемой схемы:
<xs:complexType name="QueryPgm">
<xs:sequence>
<xs:element name="NAME" type="tns:nameOptions" minOccurs="1" maxOccurs="unbounded" />
<xs:element name="SHOW" minOccurs="0" maxOccurs="unbounded">
<xs:simpleType>
<xs:annotation>
<xs:appinfo>
<jxb:typesafeEnumClass name="showOptions"/>
</xs:appinfo>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="ALL" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="STATUS" minOccurs="0" maxOccurs="unbounded">
<xs:simpleType>
<xs:annotation>
<xs:appinfo>
<jxb:typesafeEnumClass name="statusOptions"/>
<jxb:bindings node="/xs:schema/xs:complexType[@name='QueryPgm']/xs:sequence/xs:element[@name='STATUS']/xs:simpleType">
<ci:code>
@Override
public String toString() { return this.value();}
</ci:code>
</jxb:bindings>
</xs:appinfo>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="DB-NOTAVL" />
<xs:enumeration value="IOPREV" />
<xs:enumeration value="LOCK" />
<xs:enumeration value="NOTINIT" />
<xs:enumeration value="STOSCHD" />
<xs:enumeration value="TRACE" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
Я был бы признателен за помощь или идеи, которые могут возникнуть. Спасибо.
Комментарии:
1. Существует ли какой-либо сложный тип верхнего уровня с именем
QueryPgm
? Если есть, пожалуйста, включите его или вашу полную схему, если это возможно.2. ОК. Я вижу это сейчас после редактирования.
3. Рад, что вы могли это видеть; если бы не было QueryPgm, я бы получил сообщение о том, что узел документа не существует или аналогичная ошибка. К сожалению, я получаю чистый запуск, но метод code is toString() не вводится.
4. Вы решили эту проблему?
5. Дэвид, мы не решили эту проблему, у меня есть несколько других идей, которые я добавил к нашему бэклогу, чтобы попробовать, когда позволит время, а пока мы просто вручную вводим функции toString(), это только 2 или 3 места, которые нам нужны для этого, не идеально, но пока это работает.
Ответ №1:
сегодня 25 апреля 2019 года, не уверен, что автор все еще ищет решение такого рода проблем через 5 лет, в любом случае, для тех, кто заботится, отлично работает, чтобы внедрить фрагмент кода в сгенерированный класс enum с помощью jaxb (плагин jvnet). причина в том, что мы пытаемся поддерживать десериализацию xml и json с помощью устаревших классов, созданных jaxb, только с аннотациями xml. таким образом, нам действительно не нужны аннотации json с помощью каких-либо плагинов maven json (вы не можете применять как jaxb, так и плагин json для создания классов с аннотациями json и xml. было бы катастрофой). таким образом, эти устаревшие java-классы, созданные jaxb, могут использоваться для десериализации строк json (приходит ответ). а перечисление name() и value() — это боль. поскольку jaxb перешел на другой сайт с более чем 400 проблемами https://github.com/javaee/jaxb-v2 , большинство из которых даже не находятся в стадии активной разработки или будут исправлены в ближайшее время. итак, я попытался ниже исправить проблему с name() и value(), поэтому при вызове toString() экземпляра Enum вместо имен В ВЕРХНЕМ РЕГИСТРЕ может быть возвращено «реальное значение». ниже приведены некоторые фрагменты кода и информация о плагине:
файл связующего:
<jaxb:bindings schemaLocation = "locale.xsd" node = "/xs:schema">
<jaxb:bindings node = "xs:simpleType[@name='localetype']">
<ci:code>
<![CDATA[
@Override
public String toString() {
return this.value();
}
]]>
</ci:code>
</jaxb:bindings>
</jaxb:bindings>
locale.xsd
<xs:simpleType name="localetype">
<xs:restriction base="xs:string">
<xs:enumeration value="en_US"/>
<xs:enumeration value="de_DE"/>
</xs:restriction>
</xs:simpleType>
main.xsd
<xs:element name="customLocale" type="localetype"/>
плагин maven
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/schema</schemaDirectory>
<bindingDirectory>src/main/resources/schema</bindingDirectory>
<schemaIncludes>
<include>*.xsd</include>
</schemaIncludes>
<forceRegenerate>true</forceRegenerate>
<removeOldOutput>true</removeOldOutput>
<verbose>true</verbose>
<extension>true</extension>
<args>
<arg>-Xinject-code</arg>
<arg>-extension</arg>
<arg>-XhashCode</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.4</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
<version>0.6.4</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-default-value</artifactId>
<version>1.1</version>
</plugin>
</plugins>
</configuration>
</plugin>
сгенерированный класс jaxb
@XmlType(name = "localetype", namespace = "http://www.xxxx.com/ns/datatype")
@XmlEnum
public enum Localetype {
@XmlEnumValue("en_US")
EN_US("en_US"),
@XmlEnumValue("de_DE")
DE_DE("de_DE"),
private final String value;
Localetype(String v) {
value = v;
}
public String value() {
return value;
}
public static Localetype fromValue(String v) {
for (Localetype c: Localetype.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
@Override
public String toString() {
return this.value();
}
}
тестирование Джексона
compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
конфигурация клиентского кода jackson.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
не забывайте об этом:
СЧИТЫВАТЬ_ENUMS_USING_TO_STRING как true (версия jackson 2.x)