星期五, 12月 11, 2009

jboss中如何使用JAX-WS建構Web Service

由於 JBoss4.2.0GA 已經內建 jbossws-1.2.1.GA, 且 jbossws1.2.1GA 有支援 JAX-WS
現在來說明如何撰寫一個 JAX-WS web service並deploy到jboss4.2.0GA.
首先, 先撰寫 Service class First:
  package ws;
  import javax.jws.WebMethod;
  import javax.jws.WebService;

  @WebService
  public class FirstWS {
    private String message = new String("Hello, ");
    public void Hello() {}
    @WebMethod
    public String sayHello(String name) {
      return message + name + ".";
    }
  }

在 web.xml 中宣告成 servlet:
  <servlet>
    <servlet-name>WebService</servlet-name>
    <servlet-class>ws.FirstWS</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>WebService</servlet-name>
    <url-pattern>/ws</url-pattern>
  </servlet-mapping>


打包成 test.war 並丟到 deploy 目錄中並啟動 jboss.
在瀏覽器中輸入:

http://localhost:8080/test/ws?wsdl

即可看到此 web service 之 wsdl 宣告.
此篇文章重點在於如何撰寫 JAX-WS 並 deploy 到 jboss.
所以用到的 @WebService 與 @WebMethod 均未指定參數. 所以產生的 wsdl 都會是預設名稱, 這並不符合使用慣例, 至少應該宣告 namespace 資訊.
這方面的資訊不難找到, 就不多說了.

對於 Jboss 採用將其宣告為 Servlet 的方式, 雖然非常便利, 但並非標準, 會失去移植性.
且有些 IDE 會 check web.xml 裡面的 class 是否正確, 也可能會誤判.
不過相對於 RI 的部署方式, 此作法真的讓寫一個 web service 簡單太多了..
若是將 web.war 以目錄存在的方式來部署, 可以看到 jboss 會將該 Servlet 宣告轉換成另一種模式, 如下:

<servlet>
  <servlet-name>WebService</servlet-name>
  <servlet-class>org.jboss.ws.integration.jboss42.JBossServiceEndpointServlet</servlet-class>
  <init-param>
    <param-name>ServiceEndpointImpl</param-name>
    <param-value>ws.FirstWS</param-value>
  </init-param>
</servlet>


但是採用目錄的方式 deploy, 只會在第一次啟動 jboss 時可以正確運作.
第二次啟動 jboss 後, 就會失敗.
我想原因在於啟動時, jboss parse web.xml, 發現該 servlet 是一個 JAX-WS class 之後, 除了會更改掉 web.xml 之外, 還會額外產生 jboss 所需要的 classes.
但是第二次啟動, 由於讀取的是新的 web.xml, 就不會產生這些 classes, 於是就發生錯誤.
但包裝成 test.war 檔案的方式, 由於 web.xml 不會被更改掉, 於是每次啟動都不會有問題.
或許有其他方式可以避免掉這個問題(例如使用某種方式預先產生classes), 等研究出來再來補充

下次再來說如何使用 JAX-WS RI 來實作 web service...

0 Comments:

張貼留言

<< Home