概述
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 Service Developer Pack的一部分作為一個單獨的API釋出,也作為J2EE 1.4的一部分發布。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實現。預設使用有bug的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