常规
Java
SAAJ
WSDL
如果您遇到以下异常
NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
通常,此异常与使用的旧版 Xalan 有关。请确保升级到 2.7.0。
从 2.0 版开始,Spring Web Services 要求 Java 1.5 或更高版本。
Java 1.6 附带 SAAJ 1.3、JAXB 2.0 和 JAXP 1.4(Xerces 和 Xalan 的自定义版本)。通过将不同版本放在类路径中来覆盖这些库会导致各种类加载问题或异常org.apache.xml.serializer.ToXMLSAXHandler。使用较新版本的唯一方法是将较新版本放入endorsed目录(见上文)。
SAAJ 是 Java 的 SOAP 附加 API。与大多数 Java EE 库一样,它由一组接口(saaj-api.jar)和实现(saaj-impl.jar)组成。在应用程序服务器中运行时,实现通常由应用程序服务器提供。以前,SAAJ 一直是 JAXM 的一部分,但它已作为 Java Web 服务开发人员包 的一部分以及 J2EE 1.4 的一部分作为单独的 API 发布。SAAJ 通常被称为包javax.xml.soap.
Spring-WS 使用此标准 SAAJ 库来创建 SOAP 消息的表示形式。或者,它可以使用Apache AXIOM。
应用程序服务器 | SAAJ 版本 |
---|---|
BEA WebLogic 8 | 1.1 |
BEA WebLogic 9 | 1.1/1.2* |
BEA WebLogic 10 | 1.3** |
IBM WebSphere 6 | 1.2 |
SUN Glassfish 1 | 1.3 |
JBoss 4.2 | 1.3*** |
* = 请参阅下方。
** = 请参阅下方。
*** = 请参阅下方。
此外,Java SE 6 包含 SAAJ 1.3。
如果您遇到以下堆栈跟踪
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.ws.soap.saaj.SaajSoapMessageFactory' defined in ServletContext resource [/WEB-INF/springws-servlet.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.xml.soap.MessageFactory.newInstance(Ljava/lang/String;)Ljavax/xml/soap/MessageFactory; Caused by: java.lang.NoSuchMethodError: javax.xml.soap.MessageFactory.newInstance(Ljava/lang/String;)Ljavax/xml/soap/MessageFactory;
与大多数 J2EE 库一样,SAAJ 由两部分组成:由接口组成的 API(saaj-api.jar)和实现(saaj-impl.jar)。堆栈跟踪是由于您正在使用新版本的 API(SAAJ 1.3),而您的应用程序服务器提供了早期版本的实现(SAAJ 1.2 甚至 1.1)。Spring-WS 支持所有三个版本的 SAAJ(1.1 到 1.3),但在看到 1.3 API 而没有 1.3 实现时,事情就会中断。
因此,解决方案非常简单:从类路径中删除较新的 1.3 版 API,并将其替换为应用程序服务器支持的版本。
WebLogic 9 在 SAAJ 1.2 实现中存在已知错误:它实现了所有 1.2 接口,但在调用它们时会抛出UnsupportedOperationExceptions。令人困惑的是,异常消息为此类不支持 SAAJ 1.1,即使它很好地支持 SAAJ 1.1;它只是不支持 SAAJ 1.2。另请参阅此 BEA 论坛帖子。
Spring-WS 有一个解决方法,我们基本上只在处理 WebLogic 9 时才使用 SAAJ 1.1。不幸的是,其他依赖于 SAAJ 的框架(如 XWSS)没有此解决方法。这些框架会愉快地调用 SAAJ 1.2 方法,这会导致此异常。
解决方案是不使用 BEA 版本的 SAAJ,而是使用另一个实现,例如 Axis 1 或 SUN 的实现。在您的应用程序上下文中,使用以下内容
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"> <property name="messageFactory"> <bean class="com.sun.xml.messaging.saaj.soap.MessageFactoryImpl"/> </property> </bean>
Weblogic 10 附带两个 SAAJ 实现。默认情况下,使用有问题的 9.x 实现(位于包weblogic.webservice.core.soap中),但有一个新的实现支持 SAAJ 1.3(位于包weblogic.xml.saaj中)。通过查看 Spring Web Services 启动时的 DEBUG 日志,您可以查看使用了哪个 SAAJ 实现。
要使用此新版本,您必须像这样创建一个消息工厂 bean
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"> <property name="messageFactory"> <bean class="weblogic.xml.saaj.MessageFactoryImpl"/> </property> </bean>
JBoss 提供的 SAAJ 实现存在一些问题。因此,解决方案是不使用 JBoss 实现,而是使用另一个实现。例如,您可以像这样使用 SUN 的参考实现
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"> <property name="messageFactory"> <bean class="com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"/> </property> </bean>
WebSphere 捆绑了一些过时的库,需要升级到较新版本。具体来说,这包括 XML-apis、Xerces、Xalan 和 WSDL4J。
有几种方法可以升级这些库,所有这些方法都使用父级最后或应用程序优先类加载。
您可以在单独的页面上找到此问题的答案。请注意,Spring-WS 仅要求您编写 XSD;WSDL 可以从中生成。教程说明了如何操作。
&WSDL 查询参数是获取类 WSDL 的一种方法。在 SWS 中,服务通常不是作为单个类实现的,而是作为端点的集合实现的。
有两种方法可以公开 WSDL