第一部分描述如何設置NetBeans IDE和創建一個GlassFish庫。第二部分包含了關於創建一個web service工程以及用到的示例代碼的信息。最後一部分描述了利用這個工程創建你自己的web service的技巧,也作為從WSDL開始創建一個服務的指導。注意,JAX-WS2.0應用程序需要J2SE5.0。最新的JDK可以從http://Java.sun.com下載。
注意:為了使用JAS-WS2.0工作空間創建web service,而不是使用GlassFish,要了解本文所代替的這個版本。
目錄
1、設置NetBeans和GlassFish
2、建立一個工程
從Java創建一個服務
創建一個客戶端
使用NetBeans Web Services Registry
調試應用程序
3、技巧
編寫你自己的服務
從WSDL創建一個服務
設置NetBeans和GlassFish
這篇文章使用NetBeans5.0 Beta2編寫,更多關於NetBeans,包括這個應用程序的信息可以從NetBeans.org網站獲得。如果你對這個集成開發環境還很陌生,站點上的向導和指南能幫你建立環境並運行起來。
為了獲得GlassFish應用服務器,訪問GlassFish網站並點擊Download Now按鈕。按照說明書安裝一個GlassFish二進制包,使用build b28或者更新的版本。這篇文章在提及安裝文件夾時將簡化為“glassfish”文件夾。注意:由於在JAX-WS 中ant target的變化,文章中的例子只能在GlassFish build b28日期為11月23日或者更新的版本上運行。為了使用早期的版本,你必須改變wsimport及(或)wsgen target的屬性。更多細節請參照JAX-WS或者GlassFish文檔。
在NetBeans和GlassFish安裝後,使用這些步驟將服務器增加到NetBeans中,然後創建要被工程用到的GlassFish庫。在NetBeans中,點擊菜單欄中的Tools,選擇Server Manager。點擊Add Server,從Server菜單中選擇Sun Java System Application Server,然後為這個服務器輸入一個名字,例如“GlassFish”,點擊Next。在下一個屏幕上輸入你的“glassfish”文件夾的路徑,然後點擊Next,接受注冊器的默認域,點擊“Next”。在最後一屏上,輸入管理密碼,點擊“Finish”。隨包的默認密碼在GlassFish快速入門頁面上給了出來。點擊Close退出Server Manager。注意:當前在Runtime選項卡中Server節點下有兩個可用的服務器。
為了創建工程中將要用到的庫,點擊菜單欄中的Tools,然後選擇Library Manager。點擊New Library,輸入一個庫名字,例如“GlassFish”。按OK,由於“ClassPath”選項卡仍舊打開著,點擊Add JAR/Folder,浏覽你的glassfish/lib文件夾,選擇所有的jar文件(按下shift鍵同時,點擊所選文件)。點擊Add JAR/Folder,然後點擊OK。這個庫在創建服務時並不是必須的,因為在運行時GlassFish的一些jar文件已經包含在NetBeans的ClassPath中了。這個庫在稍後運行測試客戶端時將要用到。
建立一個應用程序
從Java創建一個服務
使用GlassFish創建一個web service的步驟比只使用JAX-WS代碼和包含在NetBeans之中的Tomcat服務器要簡單得多。不像那些這篇文章的這個版本中略述的步驟,在創建war文件前,你不需要使用wsgen創建服務器文件。你只需要創建服務端類,修改默認的web.XML文件,然後就可以進行發布了。
下面由創建一個新的web應用工程開始。在NetBeans中,選擇菜單欄中的File,接著選擇 New Project,在“Categories”下選擇Web,在“Project”下選擇Web Application,點擊Next。在“Project Name”一欄中輸入“SampleApp”,並且選擇保存工程的位置。確保“Server”設置成了你的GlassFish應用服務器,並且去掉對“Set Source Level to 1.4”的選擇(JAX-WS2.0需要JDK5),點擊Finish。現在這個工程已經創建了,如果願意,你也許要刪除“index.jsp”。這個工程將會用到你服務端類作為Servlet類,並且GlassFish在發布時會將這個類轉化為一個web service。
添加GlassFish庫到新的工程中。在Project選項卡中,右鍵點擊“Libraries”,選擇Add Library。選擇“GlassFish”庫,然後點擊Add Library。現在你應該告訴NetBeans,在產生的war文件中不包括GlassFish的jar文件(因為它們已經包含在了服務器中)。右鍵點擊SampleApp工程,選擇Properties。點擊左面的Library節點,去掉“Compile-time Libraries”表格中緊挨著GlassFish選項的選擇。作為一個可選(不過是有幫助的)步驟,點擊Run節點,在“Relative URL”中輸入“/hello?wsdl”。當程序運行時,它將會為這個web service的wsdl文件打開一個浏覽器。點擊OK。
增加服務類。右鍵點擊“Source Packages”,選擇New和Java Packages,輸入“my.sample.server”,點擊Finish。為了向這個包中增加一個類,在這個包節點上右鍵點擊,選擇New和Java Class。因為示例類已經寫好,你可以將ServiceImpl.java保存到SampleApp/src/java/sample/server/文件夾下,NetBeans會找到它。如果你想要查看文件的內容,只需雙擊包節點下的這個文件的名字。你可以看到它是一個包含一個方法的簡單Java類,還有一些在JAX-WS2.0運行時要用到的注釋。
保存配置文件web.xml文件到SampleApp/web/WEB-INF/文件夾下。它將覆蓋默認的那個,它指定ServiceImpl類作為servlet,以及servlet的名字,這個servlet的名字基於JAX-WS服務名+端口號。應用服務器將用到這個信息運行wsgen作為創建web service的必要條件。
為了創建和啟動服務,從菜單欄中選擇Run和Run Main Project,或者使用快捷鍵F6。NetBeans將會編譯服務類、創建war文件、啟動應用服務器和發布應用程序。如果NetBeans安裝時都進行了適當的設置,一個浏覽器將會被打開,顯示web service的wsdl文件。如果你願意你可以改變服務類,可以看到反射的wsdl發生的變化,只需要按下F6重新編譯和發布服務。
創建一個客戶端
對於一個包含web應用的完整應用程序,你將要為這個應用程序正常地創建一個新的工程。為了簡單地創建一個客戶端來測試我們新的web service,你可以使用NetBeans的單元測試功能。
由創建一個新的測試包入手。右鍵點擊Projects選項卡中“Test Packages”,選擇New和Java Packages。輸入“my.sample.test”,點擊Finish。一般來說,你可以通過右鍵點擊這個測試包和選擇New和Empty Test增加測試。對於本例,你可以保存ServiceTest.java到SampleApp/test/my/sample/test/文件夾下。打開這個文件查看測試時如何創建一個服務,然後是服務的代理器,對它調用hello(String)。注意:當你增加自己的客戶端代碼作為一個JUnit測試時,NetBeans希望名字的形式為“*Test.java”。
運行之前,增加這段xml到工程的build.xml文件中。為了編輯這個文件,你可以使用菜單欄中的File-〉Open File,或者打開Files選項卡而不是Projects,展開“SampleApp”節點,接著雙擊build.xml。NetBeans在編譯和運行測試客戶端之前就會調用這個target。當這個target運行時,它確保這個服務已經建立並且發布(如果需要重新編譯)。關於wsimport工具的更多信息參見JAX-WS文檔。
<!-- Overrides build-impl.xml target to start server and
為了運行測試,從菜單欄中選擇Run和Test Project,或者使用快捷鍵ALT-F6。在輸出信息中,你應該可以看到從這個服務返回的“hello world”。
generate client artifacts before building test. -->
<target name="-pre-compile-test">
<taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport">
<classpath path="${javac.classpath}"/>
</taskdef>
<!-- Use "debug" or "run" here. -->
<antcall target="run"/>
<echo>running wsimport</echo>
<wsimport
debug="true"
keep="true"
destdir="test"
package="my.sample.test.generated"
wsdl="http://localhost:8080/SampleApp/hello?wsdl"/>
</target>
使用NetBeans Web Services Registry
作為測試服務的一個預備的方法,你可以使用NetBeans的Web Services Registry。在Runtime選項卡中,右鍵點擊Web Services,然後選擇Add Web Service。在“URL”中輸入web service的地址,在這裡是“http://localhost:8080/SampleApp/hello?wsdl”,點擊Get Web Service Description。這將會產生有關這個web service的描述。為了測試“hello”操作,點擊緊挨著操作名稱的TestOperation。然後輸入一個要發送的值,觀察返回值(在這個要點上,為返回字符串增加一些文本來改變服務的接口類也許是非常有用的)。點擊Close退出測試,如果你想添加這個服務到注冊器中點擊Add。
調試應用程序
單步遍歷應用程序中的代碼(和JAX-WS代碼)非常簡單。由在ServiceImpl.java(15行)中的System.out.println("Service received: " + s);行上放置斷點開始。最快捷的方式就是打開文件,在要放置斷點的行上點擊編輯器的左邊框。或者將鼠標放在該行上,然後使用Ctrl-F8(關於使用調試器的全部信息參見NetBeans的用戶指南)。
在這一點上你可以在調試模式下使用Run—〉Debug Main Project啟動服務器,除此之外你也可以一步運行客戶端代碼。為了實現這個功能,改變工程中的build.xml文件中 “-pre-compile-test”target的“antcall”行,由<antcall target="run"/> 改為 <antcall target="debug"/>。
<!-- Use "debug" or "run" here. -->
<antcall target="debug"/>
現在再次運行客戶端測試(例如按下Alt-F6)。在建立測試之前,NetBeans將會在調試模式下重啟GlassFish服務器。在客戶端啟動後,調試器將會停止在ServiceImpl中適當的行上,你可以單步執行服務器代碼。注意:如果你在JAX-WS工作空間中的某一行上增加了斷點,Alt-F6將不會運行,直到你將焦點移回到SampleApp工程中的一個文件上,通過在編輯器中的產生一個文件,點擊Projects選項卡中工程等等完成。如果你對應用程序做了修改,當再一次運行測試時,所有東西都必須重新編譯。記住,為了停止測試會話,你可以通過選擇菜單欄中的Run和Finish Debugger Session,或者通過點擊工具欄中的停止按鈕。
為了測試客戶端代碼,由在ServiceTest.java中test1()方法上放置斷點開始。在Project視圖中的這個文件上右擊,選擇Debug File(或者將其作為編輯器中的活動文件,對ServiceTest使用Ctrl-Alt-F5)。它會在調試器中啟動客戶端以及服務。
技巧
編寫你自己的服務
為了編寫你自己的服務,你可以從工程中移除“my.sample.server”包,然後增加一個新的,或者按照上面的步驟創建一個新的web工程。你仍舊需要配置文件web.xml到WEB-INF文件夾下,根據需要進行修改。在web.xml中,你應該只需要修改<servlet-name>和<servlet-class>元素(也可以修改<url-pattern>)。你可以使用這個build.xml文件,它有target來保存一個步驟。
為了幫助你正確得到兩個配置文件和build.xml的值,最簡單的途徑是開始嘗試編譯,讓編譯器或者運行時錯誤來告訴你應該做什麼(別忘了查看GlassFish的輸出)。對於新的工程和新的服務文件(例如NewService.java),通過Build—〉Clean和Build Main Project或者Shift-F11進行完全地編譯,然後運行這個工程。從這一點看需要修改的地方有:
1、修改web.xml文件,使用新的servlet名字(如GlassFish日志所示)。
2、修改web.xml中的<servlet-name>以匹配新的服務名加上“Port”。(對NewService.java而言,servlet名字就是FooPort)
其它步驟就是指明在客戶端代碼中要使用的服務名稱、端口名稱和端口方法。這個可以通過運行測試完成(先將測試方法留空)。看看在build/test/classes下產生了哪些文件。為了指出wsimport工具的正確位置,改變build.xml文件中“-pre-compile”target的wsimport元素的wsdl屬性值。如果NetBeans在浏覽器中產生了發布後的服務,你可以剪切/復制這些信息。如果需要修改wsimport的“package”屬性。
從WSDL創建一個服務
為了從一個wsdl創建一個服務,主要的步驟有:增加wsdl文件,增加一個基礎的服務接口類,在build.xml文件中增加一個“-pre-compile”target而不是“-pre-dist”。如果你不知道要為服務接口類增加什麼方法或者它應該實現什麼接口,可以開始編譯工程,然後就可以從產生的代碼和編譯錯誤中快速得到所需信息。這些步驟和上面產生客戶端代碼類似。下面要用到的例子要勾畫出這些步驟的輪廓,而不是重復如由Java開始的例子的所有細節。
1、如前創建的一個新的web工程,如果你需要就移除index.jsp。增加GlassFish庫。
2、在WEB-INF目錄下,添加一個叫做“wsdl”的新文件夾,添加hello.wsdl到這個目錄下。
3、添加兩個文件web.xml和sun-jaxws.xml到WEB-INF文件夾下。注意:web.xml和從Java開始創建工程一樣。sun-jaxws.xml文件中有一些新信息:定義了終端的wsdl文件服務和端口名稱,和wsdl文件在war文件中的位置。
4、創建一個源文件包“formwsdl.sample.wsdl”,然後復制HelloImpl.java到這個包中。注意類名要匹配sun-jaxws.xml文件中指定的名字。當創建了你自己的服務,你也許從一個空的類開始,然後增加基於工程編譯時產生的代碼的接口和方法。
5、覆蓋build.xml文件的“-pre-compile”target。對於這個例子,你可以使用這個build.xml。注意服務包和wsdl信息已經在這個簡單的build.xml文件中指定了,但是客戶端測試信息並沒有。
6、一旦編譯完成,如上運行應用程序。別忘了編輯工程屬性,增加url-pattern以至於可以在浏覽器中查看服務。
-pre-compile的一般形式如下所示:
<target name="-pre-compile">
<taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport">
<classpath path="${javac.classpath}"/>
</taskdef><echo>running wsimport</echo>
<-- The wsdl attribute is absolute path, so ${basedir} is included.
The package name below will be used for the generated
interface class that your impl class must implement. -->
<wsimport
debug="true"
keep="true"
destdir="src/java"
package="YOUR_PACKAGE"
wsdl="${basedir}/web/WEB-INF/wsdl/YOUR_FILE_NAME.wsdl"/>
</target>
增加一個客戶端利用服務進行測試的步驟和上面一樣。無論是由wsdl產生的服務還是從Java類中產生的服務,客戶端都要從服務器上的wsdl文件產生。