常規

執行 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(即https://:8080/echo/echo.wsdl).

[頂部]