`
zydky
  • 浏览: 85699 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

【旧文】web service与axis(三)

阅读更多

五、利用axis开发客户端web服务

如果要使用对方提供的web服务,首先必须要有该web服务WSDL的URL,类似http://localhost:8090/webserviceTest/services/wstest?wsdl ,并对WSDL有着一定的了解。

axis支持三种web服务客户端的开发方式,分别是:

Ø         动态调用接口(Dynamic Invocation Interface)

Ø         动态代理服务(Dynamic Proxy)

Ø         静态票根(static stub)

下面分别给予介绍。

1. 动态调用接口

首先看示例代码:

package com.ufgov.webservice.client;

import java.net.URL;

import javax.xml.namespace.QName;

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

public class WsTestClient {

       private String UrlString = "http://localhost:8090/webserviceTest/services/wstest?wsdl";

       private String nameSpaceUri = "http://localhost:8090/webserviceTest/services/wstest";

       public String getNameDII(){

              try{

                     Service service = new Service();

                     Call call = (Call) service.createCall();

                     call.setOperationName(new QName(nameSpaceUri,"getName"));

                     call.setTargetEndpointAddress(new URL(UrlString));

                     String name = (String) call.invoke(new Object[]{});

                     return name;

              }

              catch(Exception e){

                     e.printStackTrace();

              }

              return null;

       }

       public static void main(String[] args){

              String name = "";

              WsTestClient  wsTestClient = new WsTestClient();

              name = wsTestClient.getNameDII();

              System.out.println("getName():" + name);

       }

}

 几点说明:

a. 在编写web服务客户端代码时,我们需要获得WSDL的URL,如http://localhost:8090/webserviceTest/services/wstest?wsdl ;需要获得web服务的URL,如http://localhost:8090/webserviceTest/services/wstest;需要获得web服务的名称,如WsTestService;需要获得web服务的端口,如wstest。

WSDL的URL一般由合作伙伴提供;web服务的URL一般是把WSDL的URL去掉后面的参数(即:“?wsdl”字样);web服务的名称对应WSDL文档里service元素的name属性;web服务的端口对应prot元素的name属性。

b. call.setOperationName()方法接受一个QName类型的参数,实例化一个QName对象需要提供web服务的URL和要调用的web服务方法。

c. call.invoke()方法接受一个Object数组参数,数组各个成员是传递给要调用的web服务方法的参数列表。

d. 如果要调用的web服务方法返回一个自定义对象,那么在客户端也需要注册自定义对象的序列化/反序列化器,代码如下:

Service service = new Service();

Call call = (Call) service.createCall();

QName qn = new QName("urn:BeanService","WsBean");

call.registerTypeMapping(WsBean.class,qn,new BeanSerializerFactory(WsBean.class,qn),new BeanDeserializerFactory(WsBean.class,qn));

call.setOperationName(new QName(nameSpaceUri,"getWsBean"));

call.setTargetEndpointAddress(new URL(UrlString));

WsBean bean = (WsBean) call.invoke(new Object[]{"myname",new Integer(20)});

 2. 动态代理服务

首先需要编写代理接口,这个接口必须继承java.rmi.Remote接口,接口提供的方法是web服务提供的所有方法的声明,并且每个接口都要抛出java.rmi.RemoteException异常,如:

package com.ufgov.webservice.client;

public interface WsTest extends java.rmi.Remote {

    public java.lang.String getName() throws java.rmi.RemoteException;

    public com.ufgov.webservice.client.WsBean getWsBean(java.lang.String name, int age) throws java.rmi.RemoteException;

}

 编写客户端代码,使用动态代理服务访问web服务,示例代码如下:

package com.ufgov.webservice.client;


import java.net.URL;

import javax.xml.namespace.QName;

import javax.xml.rpc.ServiceFactory;

import javax.xml.rpc.Service;


public class WsTestClient {

       private String UrlString = "http://localhost:8090/webserviceTest/services/wstest?wsdl";

       private String nameSpaceUri = "http://localhost:8090/webserviceTest/services/wstest";

       private String serviceName = "WsTestService";

       private String portName = "wstest";

       public String getNameDynamicProxy(){

              try{

                     URL serverUrl = new URL(UrlString);

                     ServiceFactory serviceFactory = ServiceFactory.newInstance();

                     javax.xml.rpc.Service service = serviceFactory.createService(serverUrl,new QName(nameSpaceUri,serviceName));

                     WsTest wsTest = (WsTest)service.getPort(new QName(nameSpaceUri,portName),WsTest.class);

                     String name = wsTest.getName();

                     return name;

              }

              catch(Exception e){

                     e.printStackTrace();

              }

              return null;

       }

       public static void main(String[] args){

              String name = "";

              WsTestClient  wsTestClient = new WsTestClient();

              name = wsTestClient.getNameDynamicProxy ();

              System.out.println("getName():" + name);

       }

 说明:

代理接口可以自己手工编写,这需要对WSDL比较熟悉,能够从中抽象出web服务所提供的所有方法及其参数列表、返回值类型等。还有一种选择是利用axis提供的工具生成代理接口,具体方法参见静态票根部分。

如何用动态代理的方法调用返回自定义对象的web服务方法,暂无相关资料。

3. 静态票根

要使用静态票根方法访问web服务,首先必须借助axis生成客户端代码。打开命令行窗口,转到AXIS目录下的WEB-INF子目录。确保Tomcat服务已经处于启动状态,键入命令 :

Java org.apache.axis.wsdl.WSDL2Java http://localhost:8090/webserviceTest/services/wstest?wsdl

该命令执行的结果是在当前所在目录下产生一个子目录,localhost\webserviceTest\services\wstest,该目录下有4个java源文件,分别是:

Ø         WsTest.java:定义了web服务代理接口,提供了web服务提供的所有方法的声明参见动态代理服务部分。

Ø         WsTestService.java:定义了用于获取Web服务接口的方法。

Ø        WsTestServiceLocator.java:接口WsTestService的具体实现。

Ø         WstestSoapBindingStub.java:Web服务客户端票根,通过该类与服务器交互。

命令执行后,在当前所在目录还产生一个子目录,BeanService,该目录下有自定义对象的源文件:

 

ü      WsBean.java:web服务提供者自定义的类。

 

将自动生成的java源文件拷贝到项目合适的地方,并编译。

 

编写代码访问服务,如下:

 

package com.ufgov.webservice.client;

public class WsTestClient {

    public String getNameStaticStub(){

       try{

           WsTestService service = new WsTestServiceLocator();

           WsTest wsTest = service.getwstest();

           String name = wsTest.getName();

           return name;

       }
       catch(Exception e){
           e.printStackTrace();
       }

       return null;
    }


    public static void main(String[] args){

       String name = "";

       WsTestClient  wsTestClient = new WsTestClient();

       name = wsTestClient.getNameStaticStub();

       System.out.println("getName():" + name);
    }
}

  

说明:

 

a. 执行WSDL2Java命令自动生成的子目录结构不是固定的,跟WSDL的URL有关系;

 

b. 自动生成的java源文件的名称不是固定的,跟web服务的名称有关系。

 

c. 在示例中我将自动生成的代码放在了跟客户端代码WsTestClient.java同样的包中,所以不必引入自动生成的类,否则,需要引入自动生成的类。

 

d. 使用静态票根调用返回自定义对象的web服务方法时,代码与调用返回XML Schema内置简单类型的方法无任何不同。

六、其他   

axis还支持所谓的自动部署,自动部署相当简单,但是限制也较多,网上有许多资料可以参考。个人感觉在真正的项目开发中,恐怕很少有人使用自动部署,更多的是选择通过WSDD自定义部署,也就是我们在第四部分介绍的。

(未完待续……)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics