历史
我正在从不受我控制的模式生成 Java 类。我将它导出到一个 jar,它是 Web 服务项目的依赖项。这可以正常工作。我试图将自定义绑定添加到 marshal 和 unmarshal xs:date 和 xs:dateTime 作为org.joda.DateTime
而不是XMLGregorianCalendar
. 我能够生成 jar,在 web 服务中编译它,并毫无问题地部署。然而,一旦部署,以前有效的 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
,但以前在肥皂信封中只需要一个。
问题
为什么,在添加自定义绑定之后,解析器要求我只在少数父元素上放置一个命名空间,这些父元素的子元素受自定义绑定影响?
绑定适配器
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);
}
}
绑定.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>
注释
我想强调的是,没有绑定,这完全可以正常工作,据我所知,生成的类文件是相同的(除了特定于包装器的额外注释)。SOAP 请求中使用的 xml 对 Web 服务生成的 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;
...
更新:如果我针对没有命名空间的模式执行构建,这将毫无问题。显然不是修复,而是目前的解决方法。