这篇文章说明使用NetBeans5.0和GlassFish应用服务器如何创建JAX-WS2.0服务。使用NetBeans和GlassFish的内置特征,你可以创建一个web services工程,它通过一个命令进行编译和测试。
第一部分描述如何设置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
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>
为了运行测试,从菜单栏中选择Run和Test Project,或者使用快捷键ALT-F6。在输出信息中,你应该可以看到从这个服务返回的“hello world”。
使用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文件产生。
(出处:http://www.knowsky.com)