Пользовательская привязка JAXB вызывает ошибку пространства имен
история
Я генерирую классы Java из схемы, не находящейся под моим контролем. Я экспортирую его в банку, которая является зависимостью для проекта веб-службы. Это работает правильно. Я попытался добавить пользовательскую привязку к маршалу и демаршалу xs: date и xs: dateTime в качестве экземпляров org.joda.DateTime
вместо XMLGregorianCalendar
, Я могу сгенерировать jar, скомпилировать его в веб-сервисе и развернуть без проблем. Однако после развертывания XML-запросов, которые ранее работали, теперь выдается следующее исключение:
unexpected element (uri:"", local:"ElementName"). Expected elements are <{schemaNamespace}ElementName>
Это исключение не встречается в корневом элементе. Несколько более ранних экземпляров xs: date и xs: dateTime анализируются без проблем, исключение сначала появляется в сложном типе, который содержит xs: date.
Вот пример структуры XML:
<soap:Envelope xmlns:ns="webServiceNamespace">
<soap:Body>
<request>
<root>
<child1>
<Date /> <--Works fine.
<childList>
<childListElement> <-- Exception thrown on this element.
<Date />
</childListElement>
</childList>
</child1>
</root>
</request>
</soap:Body>
</soap:Envelope>
webServiceNamespace
а также schemaNamespace
бывают разные, но раньше в мыльном конверте требовался только один.
Вопрос
Почему после добавления пользовательской привязки парсер просит меня поместить пространство имен только в несколько родительских элементов, у которых дочерняя привязка затронута пользовательской привязкой?
BindingAdapter
package myPackage;
@XmlTransient
public class JodaDateTimeAdapter extends XmlAdapter<String, DateTime> {
private static final DateTimeFormatter XML_DATE_FORMAT = ISODateTimeFormat.dateTimeNoMillis();
@Override
public DateTime unmarshal(String date) throws Exception {
return XML_DATE_FORMAT.parseDateTime(date);
}
@Override
public String marshal(DateTime dateTime) throws Exception {
return XML_DATE_FORMAT.print(dateTime);
}
}
Binding.xjb
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
jaxb:extensionBindingPrefixes="xjc"
version="2.1" >
<jaxb:globalBindings>
<xjc:javaType name="org.joda.time.DateTime" xmlType="xs:dateTime" adapter="myPackage.JodaDateTimeAdapter" />
<xjc:javaType name="org.joda.time.DateTime" xmlType="xs:date" adapter="myPackage.JodaDateAdapter" />
</jaxb:globalBindings>
</jaxb:bindings>
POM.xml (все равно соответствующие биты)
<project>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
<executions>
...
<execution>
<id>generateSchema</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<packageName>myPackage</packageName>
...
<extension>true</extension>
<arguments>-no-header -Xxew</arguments>
<bindingDirectory>src/main/bindings</bindingDirectory>
<bindingFiles>JodaBinding.xjb</bindingFiles>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.jaxb-xew-plugin</groupId>
<artifactId>jaxb-xew-plugin</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
Комментарии
Я хочу подчеркнуть, что это прекрасно работает без привязки, насколько я могу судить, сгенерированные файлы классов идентичны (за исключением дополнительных аннотаций, специфичных для оболочек). XML, используемый в запросе SOAP, действителен для WSDL, сгенерированного веб-службой, и WSDL одинаков независимо от того, использую ли я пользовательскую привязку или нет. Только элементы, которые являются членами коллекции и имеют дочерний элемент с датой, требуют пространства имен схемы. Наконец, как только я предоставляю пространства имен в своем запросе, ответ помещает объект запроса в webServiceNamespace и всех дочерних элементов, отличных от корня, определенного в схеме, в schemaNamespace. Ранее весь ответ был в webServiceNamespace.
Очевидно, что добавление пользовательского связывания делает что-то нехорошее (технический термин) с разрешением пространства имен, но я недостаточно хорошо разбираюсь в этой теме, чтобы добиться прогресса.
Предложения?
Обновление: удаление плагина XEW для создания симпатичных коллекций не повлияло на эту проблему.
Обновление: это пример класса, содержащего дату до привязки и после. Это единственное свойство для изменения:
До
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "QuestionAnswerType", propOrder = {
"question",
"answer",
"questionDate"
})
public class QuestionAnswerType {
@XmlElement(name = "Question")
protected String question;
@XmlElement(name = "Answer")
protected String answer;
@XmlElement(name = "QuestionDate")
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar questionDate;
...
После
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "QuestionAnswerType", propOrder = {
"question",
"answer",
"questionDate"
})
public class QuestionAnswerType {
@XmlElement(name = "Question")
protected String question;
@XmlElement(name = "Answer")
protected String answer;
@XmlElement(name = "QuestionDate", type = String.class)
@XmlJavaTypeAdapter(JodaDateAdapter.class)
@XmlSchemaType(name = "date")
protected DateTime questionDate;
...
Обновление: это работает без проблем, если я выполняю сборку по схеме без пространства имен. Очевидно, не решение проблемы, а обходной путь на данный момент.