WebService入门一、Hello WebService

来源:互联网 发布:淘宝网平板电脑大全 编辑:程序博客网 时间:2024/05/16 04:45

准备工作

下载最新版本的JAX-WS RI(此处为2.2.8):http://repo.maven.apache.org/maven2/com/sun/xml/ws/jaxws-ri/2.2.8/jaxws-ri-2.2.8.zip

解压后如下图所示:


  • bin目录下是两个自动生成一些文件的工具,分别是wsgen.bat(对应linux环境的wsgen.sh)和wsimport.bat(对应linux环境的wsimport.sh)。wsgen命令主要用于Server端通过Java类编译成WebService及相关的wsdl文件;wsimport则主要用于Client端(即调用端)通过wsdl文件编译出调用Server端的Java文件。
  • doc目录下是JAX-WS的发布文档。包括一些发布日志和用户手册,还有wsgen和wsimport工具的使用法及一些常见问题等等。
  • lib目录下包含Java工程所需的所有Jar包,在后面开发时需要将这些jar包导入到工程中。
  • samples目录下包含一些WebService的示例。

服务端的Hello WebService

开发环境:Spring Tool Suite

从现在开始,我们需要创建一个关于WebService的应用。

首先创建一个动态站点工程。






工程创建完成后,将JAX-WS RI解压目录下lib文件夹中的jar包都拷贝到工程中的lib目录下,同时build path这些jar包。



现在我们就可以写一个WebService的类了。在src目录下创建一个类:com.ws.Hello.java,并给这个类添加一个say方法。如下:

package com.ws;import javax.jws.WebMethod;import javax.jws.WebService;/** * WebService入门学习 * WebService注解是告诉JAXWS,这是一个WebService类 *  * @author 14040875 * */@WebServicepublic class Hello {/** * 向接收的名字问好 * WebMethod注解告诉JAXWS,此方法为soap方法 *  * @param name * @return */@WebMethodpublic String say(String name){return "Hello, " + name;}}

至此,关于WebService所需要的类就编写完成了。接下来我们需要做一些配置和生成的工作。

首先编译Hello.java文件,得到对应的class文件。这个工作可以交给STS去做,我们只需要将工程部署到Web容器上,点击发布即可。打开工程部署的位置,就可以看到编译后的Hello.class文件,如下图:


记住这个路径,稍后就会用到:D:\dev\apache-tomcat-7.0.53\webapps\HelloWebService\WEB-INF\classes\com\ws

生成JAXWS相关文件

在生成JAXWS所需要的相关文件之前,还有两件事情需要处理。首先需要给工程添加两个目录,分别是wsdl和wssrc,分别用于放置生成的配置文件和Java类文件。



接着,之前提到的两个工具wsgen和wsimport需要加入到环境变量,以便于在命令行中使用它们。设置完成后,打开命令行窗口,输入wsgen命令,回车。



如果出现上图结果,说明这个命令是可用的;反之,则不可用。如果这个命令不能用,请检查是否正确设置了环境变量,将JAXWS RI的安装目录添加到环境变量即可。

现在可以着手生成相关文件了。将命令行的工作目录切换到工程源文件所在目录。



输入以下命令并回车,为Hello类生成相关的配置文件和类文件:

wsgen -cp D:\dev\apache-tomcat-7.0.53\webapps\HelloWebService\WEB-INF\classes com.ws.Hello -wsdl -s wssrc -d build -r wsdl

其中:
  • -wsdl 表示生成的是webservice
  • -s 指出生成的.java文件放置位置
  • -d 用于提示要生成的编译class文件在何处
  • -r 表示生成.wsdl和xsd文件放于何处
  • -cp 代表classpath,也就是Hello.class的位置


现在刷新STS中的工程,就可以看到生成的一些Java类、编译后的class文件以及相关的配置文件了。



这里贴出生成xsd文件和wsdl文件的内容:

HelloService_schema1.xsd


HelloService.wsdl


在部署WebService工程之前,还要在WEB-INF目录下新建一个sun-jaxws.xml文件。如下:
<?xml version="1.0" encoding="UTF-8"?><endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'    version='2.0'>    <endpoint name='Hello' implementation='com.ws.Hello'        url-pattern='/HelloService' /></endpoints>

OK,万事具备,再为已经存在WebService配置一下访问路径,同时把一直缺失的web.xml文件补上。
<?xml version="1.0" encoding="UTF-8"?><web-app><servlet>        <span style="white-space:pre"></span><servlet-name>Hello</servlet-name>        <span style="white-space:pre"></span><servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>        <span style="white-space:pre"></span><load-on-startup>2</load-on-startup></servlet><servlet-mapping>        <span style="white-space:pre"></span><servlet-name>Hello</servlet-name>        <span style="white-space:pre"></span><url-pattern>/HelloService</url-pattern></servlet-mapping></web-app>

再次发布工程,在浏览器地址栏输入路径 http://127.0.0.1:8080/HelloWebService/HelloService?wsdl,就可以看到如下结果:


至此,WebService的服务端开发工作就完成了!

使用WebService接口

WebService接口有同步调用和异步调用来年高中方式,同步调用即为请求发出后,直到得到结果才继续执行后面的任务;异步调用则为,请求发出后,不等待返回结果,继续处理其它任务。一旦请求返回结果,再通知请求发送方。

接下来创建一个普通的Java工程,来调用刚才创建的HelloWebService接口。工程创建完成后,需要将服务端生成的wsdl文件和xsd文件拷贝到工程的wsdl目录下。


然后打开命令行窗口,将工作目录切换到Java工程所在目录,输入如下命令:

wsimport -keep -d bin -s src wsdl/HelloService.wsdl

命令执行完毕后,在STS中刷新工程,就会看到新生成很多Java文件:

需要关注的是HelloService文件中,有两处路径需要改动,一处是这个类有一个注解@WebServiceClient,其中属性wsdlLocation的值修改为刚才服务端在浏览器中输入的地址,即:http://127.0.0.1:8080/HelloWebService/HelloService?wsdl,另一处为这个类中一段static{}代码段里的url = new URL(...)也是修改为http://127.0.0.1:8080/HelloWebService/HelloService?wsdl

现在,我们可以创建一个HelloClient类,来使用我们的WebService接口:
package com.ws;public class HelloClient {public static void main(String[] args) {HelloService service = new HelloService();Hello port = service.getHelloPort();System.out.println(port.say("Mike"));}}

运行程序,就能到如下结果:

这正是之前WebService类中要做的事情:对于传入的名称,返回"Hello," + name。

异步调用WebService

上面代码为同步方式调用WebService接口,另一种异步调用的方式有时会更加有效。这里来看下,如何以异步的方式调用WebService接口。

我们重新创建一个普通的Java工程(非必要,也可以在之前的Java工程中继续操作),并将wsdl文件和xsd文件放在工程的wsdl目录下。异步调用的命令要比同步调用稍微麻烦些,需要在工程的根目录下创建一个binging.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?><bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="wsdl/HelloService.wsdl"    xmlns="http://java.sun.com/xml/ns/jaxws">    <bindings node="wsdl:definitions">        <enableAsyncMapping>true</enableAsyncMapping>    </bindings></bindings> 

同时生产Java类的命令也与同步的生成类的命令不同:
wsimport -keep –b binding.xml  -d bin -s src wsdl/HelloService.wsdl

同样,将HelloService类中的两处路径修改为http://127.0.0.1:8080/HelloWebService/HelloService?wsdl

接着创建一个测试类,还叫HelloClient吧:
package com.ws;import javax.xml.ws.Response;public class HelloClient {public static void main(String[] args) throws Exception {HelloService service = new HelloService();Hello port = service.getHelloPort();Response<SayResponse> sayAsync = port.sayAsync("Mike");while (!sayAsync.isDone()) {System.out.println("waiting...");}try {SayResponse callNameResponse = sayAsync.get();String message = callNameResponse.getReturn();System.out.println(message);} catch (Exception ex) {}}}
运行程序,得到如下结果:


当然,异步调用还有另一种“回调”方式的调用,代码如下:
package com.ws;import javax.xml.ws.AsyncHandler;import javax.xml.ws.Response;public class HelloClient {    public static void main(String[] args) throws Exception {        HelloService service = new HelloService();        Hello port = service.getHelloPort();        port.sayAsync("Mike", new AsyncHandler<SayResponse>() {            public void handleResponse(Response<SayResponse> res) {                try {                    SayResponse response = null;                    response = res.get();                    String message = response.getReturn();                    System.out.println(message);                } catch (Exception e) {                    e.printStackTrace();                }                System.out.println("Callback!");            }        });        System.out.println("begin waiting...");        Thread.sleep(1000);    }}

运行程序,得到如下结果:


0 0
原创粉丝点击