用Apache Axis实现Web Service

来源:互联网 发布:sql2005端口设置 编辑:程序博客网 时间:2024/06/10 08:38
用Apache Axis实现Web ServiceApache Axis是Apache SOAP的第三代版本,在运行速度、灵活性、稳定性等多个方面都远远超过后者。更重要的是,Axis支持WSDL(Web Service Description Language,由IBM、MS制定的Web Service描述语言规范,得到了业界最广泛的支持)。Apache Axis可以从http://ws.apache.org获得,目前的版本支持Java,也支持C++。我使用的是axis1.1,运行环境JDK1.4+Tomcat5.0,操作系统XP解压缩下载的文件到硬盘上,将webapps目录下的axis(后者axis-version)目录copy到TOMCAT_HOME/webapps下,以下将TOMCAT_HOME/webapps/axis记为AXIS_HOME。OK,访问http://localhost:8080/axis就 可以看到axis的欢迎页面了。点击Validate链接将运行happyaxis.jws,可以检查axis的配置是否正确。如果happyaxis没 有返回出错信息,则表示配置正确。如果出错,可能是axis需要的jar包缺失。把activation.jar/mail.jar /xerces.jar(其实,也可以使用其他XML parser,如JDK1.4包含的Crimson,在axis的文档中也有说明)放置到TOMCAT_HOME/commons/lib下。点击axis欢迎页的View链接,可以看到系统已发布的Web Service 列表。 二. 开发部署新的Web Service如何开发一个新Web Service并把它部署到服务器上供其他项目调用呢?有两种方式。1. 最简单的一种方式是Java Web Service,即JWS。Axis允许把普通Java类的源文件的扩展名改为.jws,然后把它简单的copy到AXIS_HOME下。这样,Axis 会自动编译.jws文件,并把它加入到Java Web Servie。其实,在ASIX_HOME,下,已经部署了几个示例jws,如,http://localhost:8080/axis/EchoHeaders.jws?method=list 。用文本编辑器打开AXIS_HOME/EchoHeader.jws,可以看到这是一个标准的java类源文件。下面,我们来自己编写并发布一个Web Service。首先, 我们编写一个最简单的Java类 HelloWorld.java package brookes; public class HelloService { public String sayHello(String username){ return "Hello, " + username; } } 然后, 把这个文件copy到AXIS_HOME,并更名为HelloWorld.jws现在,访问http://localhost:8080/HelloWorld.jws?wsdl,页面显示AXIS为HelloWorld自动生成的WSDL。这说明这个Web Service已经部署成功,可以使用了!看,开发部署一个Web Servce就是这么的简单!2。使用wsdd(Web Service Deployment Descriptor,Web服务发布描述符)文件来发布Web Service。Apache Axis使用Web 服务描述符文件(WSDD)来发布SOAP服务。要发布一个Web Service,就要为它编写一个wsdd文件。我们仍使用上面那个HelloWorld,为它编写一个wsdd文件——deploy.wsdd: 可以看到,这个wsdd文件是一个标准的XML文件,包含三个元素:元素制定了wsdd所用的XML命名空间,是这个文件的根。元素制定了一项SOAP服务。它有两个属性。name指定了这个服务的唯一标志符,provider指定了实现的语言及服务方式。一个wsdd文件可能有多个元素。指定了服务详细信息,是一组name/value对应的值。其中,clcssName指定了实现这个服务的类的名字,allowedMethods指定了这个服务暴露的方法列表。有了这个wsdd文件,我们就可以发布Web Service了。首先,编译HelloWorld.java, 把生成的HelloWorld.class文件copy到AXIS_HOME/WEB-INF/classes/brookes下,然 后,deploy.wsdd所在目录,执行命名行命令:java org.apache.axis.client.AdminClient deploy.wsdd得到如下输出:Processing file deploy.wsddDone processing这样,这个Web Service 就发布成功了。在http://localhost:8080/axis,通过点击view,就可以看到这个新发布的Web服务。这种发布方式比jws要复杂的,但是,wsdd方式可以通过WSDD描述文件,精确控制Web Service的很多特性,比如可访问的方法,因此wsdd是Web Service发布的首选方法。实际上,axis是通过ASIX_HOME/WEB-INF/server-config.wsdd文件来管理应用程序下所有Web Service。java org.apache.axis.client.AdminClient deploy.wsdd 执行的结果,就是把deploy.wsdd中的内容合并到server-config.wsdd中去。3. 在其他应用程序中发布Web Service上面都是把HelloWorld发布到http://localhost:8080的应用程序中。如果想发布到其他应用程序,或者在一个已有的应用中加入Web Service?Apache Axis的实现方式是一系列servlet,在AXIS_HOME/WEB-INF/web.xml中,可以看到这些Servlet的配置声明: Apache-Axis AxisServlet Apache-Axis Servlet org.apache.axis.transport.http.AxisServlet AdminServlet Axis Admin Servlet org.apache.axis.transport.http.AdminServlet 100 SOAPMonitorService SOAPMonitorService org.apache.axis.monitor.SOAPMonitorService SOAPMonitorPort 5001 100 AxisServlet /servlet/AxisServlet AxisServlet *.jws AxisServlet /services/* SOAPMonitorService /SOAPMonitor AdminServlet /servlet/AdminServlet wsdl text/xml xsd text/xml index.html index.jsp index.jws 可以看到,.jws和/services/*所有访问都被AxisServlet接管。这就是Axis实现Web Service 的方式。因此,在其他应用中添加Axis就变得很简单,假设要添加Axis的应用为http://localhost:8080/newweb:1.把这里所有的servlet定义都copy到newweb/WEB-INF/web.xml配置文件中。2. 将axis.jar, wsdl.jar, saaj.jar, jaxrpc.jar和其他相关类库(可以简单copy AXIS_HOME/WEB-INF/lib下所有jar)copy到newweb/WEB-INF/lib目录。3. newweb已经开发部署Web Service了!将HelloWorld.jws copy到newweb/下,访问:http://localhost:8080/newweb/HelloWorld.jws?wsdl,一切OK!需要注意的是,如果使用wsdd文件方式发布Web Service,由于org.apache.clieng.AdminclClient工具默认的是将Web Service发布到http://localhost:8080/axisAdminClient提供了一系列参数来处理这种问题,要发布到newweb,只需执行:java org.apache.axis.client.AdminClient -s /newweb/servlet/AxisServlet deploy.wsdd其中,-s参数指定了AxisServlet所在的应用程序路径。同样,如果要将Web Service发布到http://localhost/newweb,而不是默认的8080端口,需要使用 -p参数指定端口java org.apache.axis.client.AdminClient -p 80 -s /newweb/servlet/AxisServlet deploy.wsdd当然,有一个最简单的方式,就是使用-l参数指定目标应用的URL:java org.apache.axis.client.AdminClient -lhttp://localhost:8000/newweb/servlet/AxisServlet deploy.wsdd在命令行,可以通过java.org.apache.axis.client.AdminClient来查看AdminCient可用的所有参数列表。4. 删除Web Service删除Web Service的方法比较简单,jws方式发布的Web Service,删除.jws文件就可以了。使用WSDD方式发布的Web Service,仍需要使用WSDD文件删除。不过和发布不同,这个文件的根元素换成了: undeployment.wsdd 在命令行执行:java org.apache.client.AdminClient undeployment.wsddWeb Service 就被删除了!三. Web Servie的客户端使用一个Web Service部署到服务器上之后,就可以提供给其他应用程序调用。调用一个Web Service其实很简单,并不需要进行特别的设置。比如,我们前面用http://localhost:8080/axis/HelloWorld.jws?wsdl访问,就是Web Servicede 的一种调用。当然,这种说法不够严格。调用Web Service应该是调用其提供的方法,我们用这种方式调用:http://localhost:8080/axis/HelloWorld?method=sayHello&userName=brookes,结果我们得到下面的页面: Hello brookes,Welcome to my Web Service. 这是一个标准的的SOAP协议的XML回复,其中关键是元素,这就是Web Servcie对sayHello方法的响应!我们只需要解析这个XML文件,就可以得到想要的响应。(可参考XMLHttpRequest相关文档)Apache Axis支持三种客户端访问Web Service的方式:1. Dynamic Invocation Interface(DII) 动态调用接口2. Dynamic Proxy 动态代理3. Stubs 桩【注】我看到有的资料上将上面三种方式列为Web Servcie的三种“开发部署方法”,我认为说法欠妥。开发如果包含了客户端开发尚且说的过去,部署似乎更应专指服务器端。我的理解也是一家之言,欢迎指正。我们先来看DII方法,核心代码如下(我们使用了前面的HelloWorld Web服务): import org.apache.axis.client.Call; import org.apache.axis.client.Service; import javax.xml.namespace.QName; public class WsTest{ public static void main(String[] args){ try{ String endpoint = "http://localhost:8080/axis/HelloWorld.jws"; Service service = new Service(); Call call = (Call) service.createCall(); call.setOperationName(new QName( "http://localhost:8080/axis/HelloWorld.jws","sayHello")); call.setTargetEndpointAddress((endpoint); String response = (String) call.invoke(new Object[]{"Brookes"}); System.out.println("return value is: " + response); }catch (Exception ex){ ex.printStackTrace();} } } 运行程序,得到如下输出信息:return value is: Hello Brookes,Welcome to my Web Service.用DII方式访问Web Service就是这么简单!四. 用Dynamic Proxy方式访问Web ServiceDynamic Proxy的意思是动态代理,是一种很常用的设计模式,它的核心思想是:要访问对象A,向为A提供一个代理对象B,B就是对A的包装,提供和A对象相同的 接口。客户可以通过访问B对象的方法,此时,B对象负责把这个访问和实际对象(A)进行关联。这样做的好处是:代理对象B在把客户端调用传递给真实的对象 (A)之前或者之后,可执行某个附加操作,也可以选择不把这个调用传递给A,从而事实上禁止了某些操作。(这里不再详细讨论Dymamic Proxy设计模式,可baidu/google之,资料很多)Apache Axis提供了对Dynamic Proxy模式的支持。因此,我们可以先定义一个要访问的Web Service的代理接口,然后通过这个代理接口访问Web Service。下面,我们用这种方式来访问HelloWorld:首先, 编写一个代理接口HelloClientInferface.java public interface HelloClientInterface extends java.rmi.Remote{ public String sayHello(String name)throws java.rmi.RemoteException; } 需要注意的是,这个接口的方法定义必须和服务器端Web Service(HelloWorld.jws)中的定义一致,包括名称和参数。然后,就可以通过这个代理接口访问Web Service:import javax.xml.rpc.Service;import javax.xml.rpc.ServiceFactory;import java.net.URL;import javax.xml.namespace.QName;public class WsHelloWorldTestClient { public static void main(String[] args) { try{ String wsdlUrl = "http://localhost:8080/axis/HelloWorld.jws?wsdl"; String nameSpaceUri ="http://localhost:8080/axis/HelloWorld.jws"; String serviceName = "HelloWorldService"; String portName = "HelloWorld"; ServiceFactory serviceFactory = ServiceFactory.newInstance(); Service afService = serviceFactory.createService(new URL(wsdlUrl),new QName(nameSpaceUri, serviceName)); HelloClientInterface proxy = (HelloClientInterface)afService.getPort(new QName(nameSpaceUri, portName),HelloClientInterface.class); System.out.println("return value is "+proxy.sayHello("Brookes")) ; }catch(Exception ex) { ex.printStackTrace() ; } }} 代码中,serviceName和portName两个参数名,可以通过HelloWorld的WSDL文件获得。访问http://localhost:8080/axis/HelloWorld.jws?wsdl,在这个文件的尾部,可以看到这样的信息: 运行程序,得到如下输出信息:return value is: Hello Brookes,Welcome to my Web Service.五. 用Stubs方式访问Web Servicestubs在软件里的愿意是“存根”,“桩”,是为了隐藏远端调用而在系统里建立的一个代理。使用stubs封装了远程调用的复杂细节,其他类可以像调用本地类一样通过stubs使用远程功能。这里,我们仍然使用前面建立的HelloWorld.jws来说明stubs方式的使用。Axis提供了WSDL工具自动生成Stubs。WSDL2Jav的功能是通过Web Service的WSDL(Web Service Description Language)文件,自动生成java 存根类。 在命令行执行 java org.apache.axis.wsdl.WSDL2Java -p client http://localhost:8080/axis/HelloWorld.jws?wsdl执行时,确保axis/lib目录下的所有jar包都包括在了classpath中。执行成功后,在当前目录下,生成了一个client目录,其中包括4个java类文件:HelloWorld.javaHelloWorldService.javaHelloWorldServiceLocator.javaHelloWorldSoapBindingStub.java这就是可以本地访问HelloWorld的Stubs。可以通过这个Stubs访问HelloWorld: import client.*; public class TestHelloClient { public static void main(String[] args){ try{ HelloWorldService service = new client.HelloWorldServiceLocator(); HelloWorld client = service.getHelloWorld(); String retValue=client.sayHello("Brookes"); System.out.println(retValue); } catch (Exception e) { System.err.println("Execution failed. Exception: " + e); } } }执行这个程序,就会得到Web Service的返回结果:Hello Brookes,Welcome to my Web Service.Axis还提供了一个Java2WSDL工具,从Java类自动生成WSDL文件。也可以先用这个命令生成WSDL文件,如:java org.apache.axis.wsdl.Java2WSDL -oHelloWorld.wsdl -lhttp://localhost:8080/axis/service/urn:helloworld -nHelloWorld brookes.HelloWorld 然后,再使用生成的HelloWorld.wsdl文件生成Stubs。java org.apache.axis.wsdl.WSDL2Java HelloWorld.wsdl -p client关于Axis的命令行工具的使用,网上有很多的资料,可baidu/google之。
原创粉丝点击