在 SEI 型 JAX-WS Web 服務中公開方法

您可以在服務端點實作上使用 @WebService 和 @WebMethod 註釋,來指定您要公開為 Java API for XML-Based Web Services (JAX-WS) Web 服務的 Java™ 方法。

開始之前

JAX-WS 技術可同時根據標準服務端點介面和提供者介面來實作 Web 服務。 從現有的 Java 類別 (稱為由下而上方法) 開始開發 JAX-WS Web 服務時,您必須使用 @WebService 或 @WebServiceProvider 註釋來註釋類別,以起始將類別定義為 Web 服務。

使用「提供者」介面是定義 JAX-WS 服務的動態方法。 如果要使用「提供者」介面,您的類別必須實作 javax.xml.ws.Provider 介面,且包含 @WebServiceProvider 註釋。 「提供者」介面有一個方法,即 invoke 方法,在使用各種訊息或訊息有效負載時,使用 Java 程式設計語言中的通用類型來控制輸入及輸出類型。

相反地,您可以使用 Java 註釋,利用服務端點介面 (SEI) 方法來說明您的 Web 服務。

關於這項作業

若要起始定義 Web 服務,請使用 @WebService 註釋來註釋 Java 類別。 您也可以選擇性地使用 @WebMethod 註釋來註釋個別方法,以控制其公開作為 Web 服務作業。

由於多個 Web 服務規格中關於如何將方法公開為作業的語義不明確,請使用下列準則來協助確保一致行為,而不論您使用的 JAX-WS 實作為何。

  • 若要定義基本 Web 服務,請使用 @WebService 註釋來註釋實作類別。
  • 如果要使用明確的 SEI 來定義 Web 服務,請使用 @WebService 註釋的 endpointInterface 屬性來明確參照 Java 介面類別。
  • 在 @WebService 註釋的 wsdlLocation 屬性中提供 WSDL 檔的參照。 藉由指定預先定義的 WSDL 檔,可增進效能。 此外,執行時期環境會向您報告 WSDL 檔與註釋之間的不相符。
    避免麻煩: 根據 JAX-WS 2.2 規格,如果 SOAP 1.2 宣告為連結類型,且 wsdlLocation 屬性是空字串 (預設值) ,儲存器無法自動產生 WSDL。 因此,如果您使用 ?wsdl 來要求 WSDL 檔案,則會顯示下列異常狀況訊息:
    CWWKW0037E: 無法產生符合 JAX-WS 2.2 規格的 WSDL。
    如果您想要顯示 WSDL 檔,您必須手動產生 WSDL 檔,將它放在應用程式中,並指定含有正確位置的 wsdlLocation 屬性。
  • 當您使用明確的 SEI 時,會一律公開 SEI 和繼承類別中的所有公用方法。 只有在您想要進一步自訂已公開的方法時,才需要新增 @WebMethod 註釋。
  • 在 @WebService 註釋中提供明確 SEI 或現有 WSDL 檔的參照,有助於在公開方法時移除可能的語義不明確。
  • 如果您不使用明確的 SEI ,請遵循下列規則,以確保一致地公開您的方法:
    • 將 @WebService 註釋新增至實作類別及其包含您要公開之方法的所有超類別。 將 @WebService 註釋新增至類別會公開該類別中所有非 static 或 final 的公用方法。
    • 如果您想要更精細的控制項只公開特定方法,請在選取的方法上使用 @WebMethod 註釋。 若要確保公開方法,請使用 @WebMethod 註釋對其進行註釋。 如果您想要確定方法未公開,請使用 @WebMethod(exclude = true) 註釋來註釋它。
公開未標註之方法的行為變更:

在將方法公開為 Web 服務作業方面, JAX-WS 的行為已變更。 這符合 JAX-WS 規格的最新澄清。

如果應用程式沒有從舊版移轉的明確 SEI 或 WSDL ,則可能會顯示其他作業,如下所示。 您可以設定內容,讓 JAX-WS 執行時期環境使用舊式行為。 當移轉沒有 WSDL 或 SEI 的應用程式時,您可能需要此項,以便不會公開其他方法。

@WebService
public class Foo {
	@WebMethod
	public void a() {}	// exposed now, exposed before
	public void b() {}	// exposed now, not exposed before
}
使用新的解譯,實作類別及其超類別中的公用方法僅在下列條件下公開:
  • 包含類別具有 @WebService 註釋。
  • 方法沒有 @WebMethod(exclude = true) 註釋。
使用舊式解譯時,實作類別及其超類別中的方法僅在下列條件下公開:
  • 包含類別具有 @WebService 註釋。
  • 此方法沒有 @WebMethod 註釋,且沒有其他方法有 @WebMethod 註釋。
  • 方法具有 @WebMethod 或 @WebMethod(exclude=false) 註釋。

如果要指定 JAX-WS 執行時期環境使用舊式 @WebMethod 行為,請配置 jaxws.runtime.legacyWebMethod=true 內容。 您可以將這個內容配置成 Java 虛擬機器 (JVM) 系統內容,或配置成 Web 應用程式保存檔 (WAR) 的 META-INF/MANIFEST.MF 檔中的內容。 依預設,這個內容會設為 false ,且應用程式伺服器會使用新的行為。

如果符合下列所有條件,您可能會遇到 WSWS7054E 錯誤訊息:
  • 您的 Web 服務應用程式是由未註釋的方法所組成。
  • 這些方法不是要對映至 Web 服務作業。
  • 您的應用程式不會參照 SEI ,也不會包裝 WSDL 檔。
錯誤訊息包含類似下列文字的資訊:
javax.xml.ws.WebServiceException: WSWS7054E:
 無法為 XXXX Web 服務實作產生「Web 服務說明語言 (WSDL)」檔案
 類別,因為發生下列錯誤 :javax.xml.ws.WebServiceException: Unable to create JAXBContext
在 @WebMethod 對映原則方面, JAX-WS 工具符合 JAX-WS 規格。 這項變更可能會影響已相依於先前不符合標準的預設行為的應用程式。 如果您的應用程式套件和參照 WSDL 或 SEI ,且在 SEI 實作中正確標註了 @WebMethod 排除旗標的 ALL 方法,則這項變更不會影響您。 不過,如果您受到影響,請將明確註釋新增至您的方法,以確保在 WSDL 產生中排除它們。 例如: @WebMethod(exclude = true) 此外,您也可以將 WSDL 與應用程式包裝在一起,不需要執行時期代表您產生 WSDL。
公開 static 和 final 方法的行為變更:

服務中沒有明確 SEI 的 static 或 final 方法不再公開為 Web 服務作業。 若要公開它們,請將 WSDL 與應用程式包裝在一起,並設定 jaxws.runtime.legacyWebMethod=true

程序

  1. 識別您要公開為 Web 服務作業的方法。
  2. 檢閱在以 @WebService 註釋標註的類別上公開方法作為作業的規則。
  3. 使用最佳作法在沒有 SEI 的應用程式中套用 @WebMethod 及 @WebService 註釋,以適當地將方法公開為 Web 服務內的作業。

結果

您已使用 @WebMethod 註釋來指定要公開為 Web 服務作業的方法。

避免麻煩: 如果您已升級應用程式伺服器環境,且遇到問題,請檢閱下列疑難排解資訊。
使用 JAX-WS 工具 2.1.6 版或更新版本環境時,用戶端錯誤指出 WSDL 檔與 portType 之間不符
您可能會收到類似下列訊息的用戶端錯誤訊息:
javax.xml.ws.WebServiceException: 端點驗證無法驗證,因為發生下列錯誤:
* 端點介面無效 ::
* WSDL portType 中的作業數不符合 SEI 或 Web 服務中的方法數
 實作類別。  wsdl 作業 = [...] 分派作業 = [....]

如果要更正這個問題,您必須重新產生用戶端構件,以符合 WSDL 檔。

每當您收到更新的 WSDL 檔時,請務必重新產生用戶端構件。

執行的客戶?Web 服務上的 WSDL 作業具有不可分派的作業
在執行之後?WSDL 作業,您可能會收到 WSDL 檔,其中包含的作業數超過 JAX-WS 執行時期環境所能分派的數目。 如果用戶端嘗試呼叫任何不可分派的作業,用戶端會收到類似下列訊息的錯誤:
找不到作業的端點參照 (EPR) 是 http://localhost:9086/example/BeanImpl2Service 和 WSA 
Action = <WSA_action_from_server>. If this EPR was previously reachable, contact the server administrator.

用戶端只能存取 Web 服務想要公開的作業。 您可以使用下列其中一種方式來更正此問題:

  • 修改 Web 服務應用程式中的 @WebMethod 註釋,使產生的 WSDL 檔顯現一組正確的作業。
  • jaxws.runtime.legacyWebMethod 內容設為 false ,以確保已分派 WSDL 中的所有作業。

下一步

從 JavaBeans 開發 JAX-WS 應用程式的 Java 構件