Пользовательская привязка 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;
      ...

Обновление: это работает без проблем, если я выполняю сборку по схеме без пространства имен. Очевидно, не решение проблемы, а обходной путь на данный момент.

0 ответов

Другие вопросы по тегам