常规

运行 Spring Web Services 是否需要任何其他 SOAP 框架?
您不需要任何其他 SOAP 框架来使用 Spring Web 服务,尽管它可以使用 Axis 1 和 2 的某些功能。

[顶部]


我得到NAMESPACE_ERR在使用 Spring-WS 时出现异常。我该怎么办?

如果您收到以下异常

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。

[顶部]

Java

Spring-WS 是否在 Java 1.3 或 1.4 下运行?

从 2.0 版开始,Spring Web Services 需要 Java 1.5 或更高版本。

[顶部]


Spring-WS 是否在 Java 1.6 下工作?

Java 1.6 附带 SAAJ 1.3、JAXB 2.0 和 JAXP 1.4(Xerces 和 Xalan 的自定义版本)。 通过将不同版本放在类路径上来覆盖这些库会导致各种类加载问题,或者在org.apache.xml.serializer.ToXMLSAXHandler中出现异常。 使用更新版本的唯一选择是将更新的版本放在endorsed目录中(见上文)。

[顶部]

SAAJ

什么是 SAAJ?

SAAJ 是 Java 的 SOAP with Attachments API。 像大多数 Java EE 库一样,它由一组接口 (saaj-api.jar) 和实现 (saaj-impl.jar) 组成。 在应用程序服务器中运行时,该实现通常由应用程序服务器提供。 以前,SAAJ 一直是 JAXM 的一部分,但它已作为 Java Web Service Developer Pack 的一部分以及 J2EE 1.4 的一部分作为单独的 API 发布。 SAAJ 通常被称为包javax.xml.soap.

Spring-WS 使用此标准 SAAJ 库来创建 SOAP 消息的表示。 或者,它可以使用 Apache AXIOM

[顶部]


我的应用程序服务器支持哪个版本的 SAAJ?
应用程序服务器SAAJ 版本
BEA WebLogic 81.1
BEA WebLogic 91.1/1.2*
BEA WebLogic 101.3**
IBM WebSphere 61.2
SUN Glassfish 11.3
JBoss 4.21.3***

* = 请参阅 下文

** = 请参阅 下文

*** = 请参阅 下文

此外,Java SE 6 包括 SAAJ 1.3。

[顶部]


我得到一个NoSuchMethodError在使用 SAAJ 时出现异常。我该怎么办?

如果您获得以下堆栈跟踪

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,并将其替换为应用程序服务器支持的版本。

[顶部]


我得到一个UnsupportedOperationException“此类不支持 SAAJ 1.1”,当我在 WebLogic 9 下使用 SAAJ 时。我该怎么办?

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>
                   

[顶部]


我得到一个UnsupportedOperationException“此类不支持 SAAJ 1.1”,当我在 WebLogic 10 下使用 SAAJ 时。我该怎么办?

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>
                   

[顶部]


我得到一个IndexOutOfBoundsException当我在 JBoss 下使用 SAAJ 时。我该怎么办?

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>
                   

[顶部]


Spring-WS 是否在 IBM WebSphere 上运行?

WebSphere 捆绑了一些过时的库,需要使用更新的版本进行升级。 具体来说,这包括 XML-apis、Xerces、Xalan 和 WSDL4J。

有几种方法可以升级这些库,所有方法都使用 parent-last 或 application-first 类加载。

  • 将库作为 WAR 的一部分打包(在 WEB-INF/lib 中),并使用 parent-last(application-first)类加载运行 Web 应用程序。
  • 将库作为 EAR 的一部分打包,将类路径条目添加到 Web 应用程序的清单中,并使用 parent-last 类加载运行整个应用程序。
  • 在 WebSphere 控制台中创建一个新的类加载器,并将库与该类加载器关联。 将此类加载器设置为 parent-last。
最后一种方法的优点是将 parent-last 类加载限制为仅冲突的库,而不是整个应用程序。

[顶部]

WSDL

为什么 Spring-WS 仅支持合约优先?

您可以在单独的页面上找到此问题的答案。 请注意,Spring-WS 只需要您编写 XSD; WSDL 可以从中生成。 本教程说明了如何操作。

[顶部]


如何从服务中检索 WSDL? &WSDL 查询参数不起作用。

&WSDL 查询参数是一种获取类 WSDL 的方法。 在 SWS 中,服务通常不是作为单个类实现的,而是作为端点的集合实现的。

有两种方法可以公开 WSDL

  • 只需将 WSDL 添加到 WAR 的根目录,该文件即可正常提供。 这样做的不利之处在于 WSDL 中的“location”属性是静态的,即它不一定反映服务器的主机名。 您可以使用 WsdlDefinitionHandlerAdapter 来转换位置。
  • 使用MessageDispatcherServlet,在示例中完成。 每个WsdlDefinition都在*-servlet.xml中列出,将在 bean 名称下公开。 所以如果你定义一个WsdlDefinition名为echo,它将被公开为echo.wsdl(即http://localhost:8080/echo/echo.wsdl).

[顶部]