GVKun编程网logo

WebService之--------Axis2准备工作(axis2 webservice)

6

本文将介绍WebService之--------Axis2准备工作的详细情况,特别是关于axis2webservice的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同

本文将介绍WebService之--------Axis2准备工作的详细情况,特别是关于axis2 webservice的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于Axis2 WebService 客户端 Axis2 调用、Axis2 WebService之会话管理(Session)、axis2实现webservice之使用services.xml文件发布WebService、axis2实现WebService之用POJO实现0配置的WebService的知识。

本文目录一览:

WebService之--------Axis2准备工作(axis2 webservice)

WebService之--------Axis2准备工作(axis2 webservice)

Axis2的优点:支持多种语言,C,Java,C#等。

    1:准备Axis2所需的jar包和War包,下载地址:

                                 http://axis.apache.org/axis2/java/core/download.cgi

                                        

 

     2:然后下载Eclipse的Axis插件工具,可以打包(aar)及其生产客户端调用代码,有2个插件。    
                 http://axis.apache.org/axis2/java/core/tools/index.html 
                           

                         
 
           3.把插件安装到Eclipse,安装成功如图所示:

          
           4.把刚下载的 axis2.war 包放在TomCat里的WebApps中,此时是否有点不解,别急,当部署Tom时他会自动把这War包解压出来,是一个可运行的项目,在部署完之后当你就可以看到那项目。在浏览器中运行出现如图所示,说明你Very Good!
                      
                

                                       
    在这说明下,我用的是MyEclispe,本想用Eclispe的,它运行起来比较快,但是就是没法成功,部署Tom之后运行下,总是报404,不知道为什么,如您知道请您告诉声,谢谢!  我的都是精简出主要的,以下博客都是很详细,可以查看下。
                                    
 
在此感谢以下博友:
  http://www.cnblogs.com/hoojo/archive/2011/03/15/1985165.html
http://www.voidcn.com/article/p-nlffpjrr-bcy.html

Axis2 WebService 客户端 Axis2 调用

Axis2 WebService 客户端 Axis2 调用

第一 RPC 方式,不生成客户端代码

第二,document 方式,不生成客户端代码

第三,用 wsdl2java 工具,生成客户端方式调用

 

package samples.quickstart.client;  
  
import javax.xml.namespace.QName;  
import org.apache.axiom.om.OMAbstractFactory;  
import org.apache.axiom.om.OMElement;  
import org.apache.axiom.om.OMFactory;  
import org.apache.axiom.om.OMNamespace;  
import org.apache.axis2.AxisFault;  
import org.apache.axis2.addressing.EndpointReference;  
import org.apache.axis2.client.Options;  
import org.apache.axis2.client.ServiceClient;  
import org.apache.axis2.rpc.client.RPCServiceClient;  
import samples.quickstart.StockQuoteServiceStub;  
import samples.quickstart.xsd.GetPrice;  
import samples.quickstart.xsd.GetPriceResponse;  
  
public class StockQuoteClient {  
  
  /** 
   * 方法一: 
   * 应用rpc的方式调用 这种方式就等于远程调用, 
   * 即通过url定位告诉远程服务器,告知方法名称,参数等, 调用远程服务,得到结果。 
   * 使用 org.apache.axis2.rpc.client.RPCServiceClient类调用WebService 
   * 
    【注】: 
     
        如果被调用的WebService方法有返回值 应使用 invokeBlocking 方法 该方法有三个参数 
          第一个参数的类型是QName对象,表示要调用的方法名; 
          第二个参数表示要调用的WebService方法的参数值,参数类型为Object[]; 
            当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。 
          第三个参数表示WebService方法的 返回值类型的Class对象,参数类型为Class[]。 
         
         
        如果被调用的WebService方法没有返回值 应使用 invokeRobust 方法 
          该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。 
 
        在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名, 
        也就是 <wsdl:definitions>元素的targetNamespace属性值。 
   * 
   */  
  public static void testRPCClient() {  
    try {  
      // axis1 服务端  
// String url = "http://localhost:8080/StockQuote/services/StockQuoteServiceSOAP11port?wsdl";  
      // axis2 服务端  
      String url = "http://localhost:8080/axis2ServerDemo/services/StockQuoteService?wsdl";  
  
      // 使用RPC方式调用WebService  
      RPCServiceClient serviceClient = new RPCServiceClient();  
      // 指定调用WebService的URL  
      EndpointReference targetEPR = new EndpointReference(url);  
      Options options = serviceClient.getOptions();  
      //确定目标服务地址  
      options.setTo(targetEPR);  
      //确定调用方法  
      options.setAction("urn:getPrice");  
  
      /** 
       * 指定要调用的getPrice方法及WSDL文件的命名空间 
       * 如果 webservice 服务端由axis2编写 
       * 命名空间 不一致导致的问题 
       * org.apache.axis2.AxisFault: java.lang.RuntimeException: Unexpected subelement arg0 
       */  
      QName qname = new QName("http://quickstart.samples/xsd", "getPrice");  
      // 指定getPrice方法的参数值  
      Object[] parameters = new Object[] { "13" };  
        
      // 指定getPrice方法返回值的数据类型的Class对象  
      Class[] returnTypes = new Class[] { double.class };  
  
      // 调用方法一 传递参数,调用服务,获取服务返回结果集  
      OMElement element = serviceClient.invokeBlocking(qname, parameters);  
      //值得注意的是,返回结果就是一段由OMElement对象封装的xml字符串。  
      //我们可以对之灵活应用,下面我取第一个元素值,并打印之。因为调用的方法返回一个结果  
      String result = element.getFirstElement().getText();  
      System.out.println(result);  
  
      // 调用方法二 getPrice方法并输出该方法的返回值  
      Object[] response = serviceClient.invokeBlocking(qname, parameters, returnTypes);  
      // String r = (String) response[0];  
      Double r = (Double) response[0];  
      System.out.println(r);  
  
    } catch (AxisFault e) {  
      e.printStackTrace();  
    }  
  }  
  
  /** 
   * 方法二: 应用document方式调用 
   * 用ducument方式应用现对繁琐而灵活。现在用的比较多。因为真正摆脱了我们不想要的耦合 
   */  
  public static void testDocument() {  
    try {  
      // String url = "http://localhost:8080/axis2ServerDemo/services/StockQuoteService";  
      String url = "http://localhost:8080/StockQuote/services/StockQuoteServiceSOAP11port?wsdl";  
  
      Options options = new Options();  
      // 指定调用WebService的URL  
      EndpointReference targetEPR = new EndpointReference(url);  
      options.setTo(targetEPR);  
      // options.setAction("urn:getPrice");  
  
      ServiceClient sender = new ServiceClient();  
      sender.setOptions(options);  
        
        
      OMFactory fac = OMAbstractFactory.getOMFactory();  
      String tns = "http://quickstart.samples/";  
      // 命名空间,有时命名空间不增加没事,不过最好加上,因为有时有事,你懂的  
      OMNamespace omNs = fac.createOMNamespace(tns, "");  
  
      OMElement method = fac.createOMElement("getPrice", omNs);  
      OMElement symbol = fac.createOMElement("symbol", omNs);  
      // symbol.setText("1");  
      symbol.addChild(fac.createOMText(symbol, "Axis2 Echo String "));  
      method.addChild(symbol);  
      method.build();  
        
      OMElement result = sender.sendReceive(method);  
  
      System.out.println(result);  
  
    } catch (AxisFault axisFault) {  
      axisFault.printStackTrace();  
    }  
  }  
  
 /** 
  * 为SOAP Header构造验证信息, 
  * 如果你的服务端是没有验证的,那么你不用在Header中增加验证信息 
  * 
  * @param serviceClient 
  * @param tns 命名空间 
  * @param user 
  * @param passwrod 
  */  
  public void addValidation(ServiceClient serviceClient, String tns , String user, String passwrod) {  
    OMFactory fac = OMAbstractFactory.getOMFactory();  
    OMNamespace omNs = fac.createOMNamespace(tns, "nsl");  
    OMElement header = fac.createOMElement("AuthenticationToken", omNs);  
    OMElement ome_user = fac.createOMElement("Username", omNs);  
    OMElement ome_pass = fac.createOMElement("Password", omNs);  
      
    ome_user.setText(user);  
    ome_pass.setText(passwrod);  
      
    header.addChild(ome_user);  
    header.addChild(ome_pass);  
  
    serviceClient.addHeader(header);  
  }  
  
    
  /** 
   * 方法三:利用axis2插件生成客户端方式调用 
   * 
   */  
  public static void testCodeClient() {  
    try {  
      String url = "http://localhost:8080/axis2ServerDemo/services/StockQuoteService";  
      StockQuoteServiceStub stub = new StockQuoteServiceStub(url);  
      GetPrice request = new GetPrice();  
      request.setSymbol("ABCD");  
      GetPriceResponse response = stub.getPrice(request);  
      System.out.println(response.get_return());  
    } catch (org.apache.axis2.AxisFault e) {  
      e.printStackTrace();  
    } catch (java.rmi.RemoteException e) {  
      e.printStackTrace();  
    }  
  
  }  
  
  public static void main(String[] args) {  
     StockQuoteClient.testRPCClient();  
// StockQuoteClient.testDocument();  
    // StockQuoteClient.testCodeClient();  
  
  }  
}  

 

wsdl2java 用于根据 WSDL 生成相应的服务端和客户端代码的生成工具。
命令行格式为:WSDL2Java [options] -uri <url or path> : A url or path to a WSDL

例如:

wsdl2java -uri http://localhost:8080/cxfService_0617/services/Hellows?wsdl -s -o build\client

 

其中常用的 options 具体如下:
-o <path> : 指定生成代码的输出路径
-a : 生成异步模式的代码
-s : 生成同步模式的代码
-p <pkg> : 指定代码的 package 名称
-l <languange> : 使用的语言 (Java/C) 默认是 java
-t : 为代码生成测试用例
-ss : 生成服务端代码 默认不生成
-sd : 生成服务描述文件 services.xml, 仅与 - ss 一同使用
-d <databinding> : 指定 databingding,例如,adb,xmlbean,jibx,jaxme and jaxbri
-g : 生成服务端和客户端的代码
-pn <port_name> : 当 WSDL 中有多个 port 时,指定其中一个 port
-sn <serv_name> : 选择 WSDL 中的一个 service
-u : 展开 data-binding 的类
-r <path> : 为代码生成指定一个 repository
-ssi : 为服务端实现代码生成接口类
-S : 为生成的源码指定存储路径
-R : 为生成的 resources 指定存储路径
–noBuildXML : 输出中不生成 build.xml 文件
–noWSDL : 在 resources 目录中不生成 WSDL 文件
–noMessageReceiver : 不生成 MessageReceiver 类

Axis2 WebService之会话管理(Session)

Axis2 WebService之会话管理(Session)

首先保证你已配置好Axis2。

 

实现同一个WebServiceSession管理需要如下三步:

 

1. 使用MessageContextServiceContext获得与设置key-value对。

2. 为要进行Session管理的WebService类所对应的<service>元素添加一个scope属性,并将该属性值设为transportsession

3. 在客户端使用setManageSession(true)打开Session管理功能。

 

下面是一个在同一个WebService类中管理Session的例子

 

在Eclipse中新建一个webservice工程,如命名为:SessionWebService,建立一个WebService类,代码如下:

 

package service;
import org.apache.axis2.context.ServiceContext;
 org.apache.axis2.context.MessageContext;
public class LoginService
{
    
boolean login(String username, String password)
    {
        
if("bill".equals(username) && "1234".equals(password))
        {
            
//  1步:设置key-value
            MessageContext mc = MessageContext.getCurrentMessageContext();
            ServiceContext sc = mc.getServiceContext();
            sc.setProperty("login", "
成功登录");    
            
returntrue;
        }
        
else
        {
            
false;
        }
    }
    
public String getLoginMsg()
    {
        
步:获得对中的value
        MessageContext mc = MessageContext.getCurrentMessageContext();
        ServiceContext sc = mc.getServiceContext();
        
return (String)sc.getProperty("login");    
    }
}

LoginService类中有两个方法:logingetLoginMsg,如果login方法登录成功,会将“成功登录”字符串保存在ServiceContext对象中。如果在login方法返回true后调用getLoginMsg方法,就会返回“成功登录”。

下面是LoginService类的配置代码(services.xml):

<!--  2步:添加scope属性  -->
<service name="loginService" scope="transportsession">
    description>
        登录服务
        </parameter ="ServiceClass">
        service.LoginService
        
parametermessageReceiversmessageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class="org.apache.axis2.rpc.receivers.RPcmessageReceiver" />service>

 

使用如下的命令生成客户端使用的stub类:

%AXIS2_HOME%/bin/wsdl2java -uri http://localhost:8080/axis2/services/loginService?wsdl -p client -s -o stub

stub/src/client目录中生成了一个LoginServiceStub.java类,在该类中找到如下的构造句方法:

public LoginServiceStub(org.apache.axis2.context.ConfigurationContext configurationContext,
        java.lang.String targetEndpoint, 
boolean useSeparateListener)
        
throws org.apache.axis2.AxisFault 
{
    
 
    _serviceClient.getoptions().setSoapVersionURI(
                                 org.apache.axiom.soap.soAP12Constants.soAP_ENVELOPE_NAMESPACE_URI);
}

在该方法中最后添加如下的代码://  3步:打开客户端的Session管理功能
_serviceClient.getoptions().setManageSession(true);

 

 

下面的客户端代码使用LoginServiceStub对象访问了刚才建立的WebService

package test;

import client.LoginServiceStub;

public class TestClient
{
 public static void main(String[] args)
 {
  try
  {
   LoginServiceStub stub = new LoginServiceStub();
   LoginServiceStub.Login login = new LoginServiceStub.Login();
   login.setUsername("bill");
   login.setPassword("1234");
   if(stub.login(login).local_return)
   {
       System.out.println(stub.getLoginMsg().local_return);
   }
  }
  catch (Exception e)
  {
       e.printstacktrace();
  }
 }
}

运行上面的代码后,会输出“成功登录”信息。

axis2实现webservice之使用services.xml文件发布WebService

axis2实现webservice之使用services.xml文件发布WebService

       还是对教程的延伸,本来是周五要写的,但是耽搁了一下,就拖到周一了。

      Axis2实现Web Service,虽然可以将POJO类放在axis2\WEB-INF\pojo目录中直接发布成Web Service,这样做不需要进行任何配置,但这些POJO类不能在任何包中。这似乎有些不方便,为此,Axis2也允许将带包的POJO类发布成Web Service
   
先实现一个POJO类,代码如下: 

package service; public class MyService { public String getGreeting(String name) { return "您好 " + name; } public void update(String data) { System.out.println("<" + data + ">已经更新"); } }

这个类有两个方法,这两个方法都需要发布成Web Service方法。这种方式和直接放在pojo目录中的POJO类不同。要想将MyService类发布成Web Service,需要一个services.xml文件,这个文件需要放在meta-inf目录中,该文件的内容如下:

<service name="myService"> <description> Web Service例子 </description> <parameter name="ServiceClass"> service.MyService </parameter> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"https://www.jb51.cc/tag/cme/" target="_blank">cmessageReceiver" /> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"/> </messageReceivers> </service>

其中<service>元素用于发布Web Service,一个<service>元素只能发布一个WebService类,name属性表示WebService名,如下面的URL可以获得这个WebServiceWSDL内容:

http://localhost:8080/axis2/services/myService?wsdl (这个得等到.aar文件出来之后)

其中name属性名就是上面URL"?""/"之间的部分。

<description>元素表示当前Web Service的描述,<parameter>元素用于设置WebService的参数,在这里用于设置WebService对应的类名。在这里最值得注意的是<messageReceivers>元素,该元素用于设置处理WebService方法的处理器。例如,getGreeting方法有一个返回值,因此,需要使用可处理输入输出的RPcmessageReceiver类,而update方法没有返回值,因此,需要使用只能处理输入的RPCInOnlyMessageReceiver类。

使用这种方式发布WebService,必须打包成.aar文件,..aar文件实际上就是改变了扩展名的.jar文件。在现在建立了两个文件(这两个文件夹任意):MyService.javaservices.xml。将MyService.java编译,生成MyService.classservices.xmlMyService.class文件的位置如下:

D:\ws\service\MyService.class

D:\ws\meta-inf\services.xml

   
 windows控制台中进入ws目录,并输入如下的命令生成.aar文件(实际上,.jar文件也可以发布webservice,但axis2官方文档中建议使用.aar文件发布webservice):

jar cvf ws.aar .    jar cvf AxisTest.aar .

    如下是我测试的过程

        原来发现不管要.aar,之后还需要一个“.”,即.arr.,但是最坑爹的就是这里了,加了“.”之后还是不对啊,最后的问题居然是这个后面的点要空一格,不能紧挨着.arr


      如下成功之后的文件夹情况


    最后将ws.aar文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中,启动Tomcat后,就可以调用这个WebService了。

      已经显示webservice发布成功了,接下来就是编写客户端进行调运了,跟前面一样,也需要wsdl2java命令去生成stub类,过程我就不多说了,之前的博客里有

如下是调用客户端的代码

package service; import org.apache.axis2.AxisFault; public class MyServiceStubClient { public static void main(String[] args) { // Todo Auto-generated method stub try { MyServiceStub mss = new MyServiceStub(); MyServiceStub.GetGreeting gg = new MyServiceStub.GetGreeting(); MyServiceStub.Update up = new MyServiceStub.Update(); gg.setName("美女"); up.setData("帅哥"); try { mss.update(up); System.out.println("美女"+mss.getGreeting(gg).get_return()); } catch (Exception e) { // Todo Auto-generated catch block e.printstacktrace(); System.out.println("发生异常"); } } catch (AxisFault e) { // Todo Auto-generated catch block e.printstacktrace(); } } }


运行结果

由于“帅哥”是在服务器端打印的,所以客户端是看不到的。

在打包arr文件的时候,发现有一个build.xml文件,这个是ant脚本中的知识,在本题中暂时不涉及,以后再介绍。

 

如果想发布多个WebService,可以使用<serviceGroup>元素,如再建立一个MyService1类,代码如下:

package service public class MyService1 { public String getName() { return "bill"; } }


services.xml文件中可以使用如下的配置代码来配置MyServiceMyService1类:

<serviceGroup> <service name="myService"> <description> Web Service例子 </description> <parameter name="ServiceClass"> service.MyService </parameter> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"https://www.jb51.cc/tag/cme/" target="_blank">cmessageReceiver" /> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"/> </messageReceivers> </service> <service name="myService1"> <description> Web Service例子 </description> <parameter name="ServiceClass"> service.MyService1 </parameter> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"https://www.jb51.cc/tag/cme/" target="_blank">cmessageReceiver" /> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"/> </messageReceivers> </service> </serviceGroup>

axis2实现WebService之用POJO实现0配置的WebService

axis2实现WebService之用POJO实现0配置的WebService

参照着网上的教程,自己做了一遍,发现教程是错误百出啊,搞得我弄了一个下午才搞好,废话少说,看招!

一、Axis2的下载和安装

    读者可以从如下的网址下载Axis2的最新版本:

    http://ws.apache.org/axis2/

    在本文使用了目前Axis2的最新版本1.6.2。读者可以下载如下两个zip包:

    axis2-1.4.1-bin.zip   f3d04032c142898c206a1312d8385d9a  
    axis2-1.4.1-war.zip   51a77ec0a47483cdfd8166797bdc977e 

    其中axis2-1.6.2-bin.zip文件中包含了Axis2中所有的jar文件,axis2-1.6.2-war.zip文件用于将WebService发布到Web容器中。

    axis2-1.6.2-war.zip文件解压到相应的目录,将目录中的axis2.war文件放到<Tomcat安装目录>\webapps目录中(本文使用的Tomcat的版本是6.x),并启动Tomcat

    在浏览器地址栏中输入如下的URL

    http://localhost:8080/axis2/

    如果在浏览器中显示出如图1所示的页面,则表示Axis2安装成功。

二、编写和发布WebService

     对于用Java实现的服务程序给人的印象就是需要进行大量的配置,不过这一点在Axis2中将被终结。在Axis2中不需要进行任何的配置,就可以直接将一个简单的POJO发布成WebService。其中POJO中所有的public方法将被发布成WebService方法。

    下面我们来实现一个简单的POJO,代码如下:

public class SimpleService { public String getGreeting(String name) { return "你好 " + name; } public int getPrice() { return new java.util.Random().nextInt(1000); } }

 

 SimpleService类中有两个方法,由于这两个方法都是public方法,因此,它们都将作为WebService方法被发布。

    编译SimpleService类后,将SimpleService.class文件放到<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中(如果没有pojo目录,则建立该目录)。现在我们已经成功将SimpleService类发布成了WebService。在浏览器地址栏中输入如下的URL

http://localhost:8080/axis2/services/listServices

    这时当前页面将显示所有在Axis2中发布的WebService,如图2所示。

在浏览器地址栏中输入如下的两个URL来分别测试getGreetinggetPrice方法:

http://localhost:8080/axis2/services/SimpleService/getGreeting?name=bill

http://localhost:8080/axis2/services/SimpleService/getPrice

   
 3和图4分别显示了getGreetinggetPrice方法的测试结果。

 在编写、发布和测试0配置的WebService时应注意如下几点:

    1. POJO类不能使用package关键字声明包。

    2. Axis2在默认情况下可以热发布WebService,也就是说,将WebService.class文件复制到pojo目录中时,Tomcat不需要重新启动就可以自动发布WebService。如果想取消Axis2的热发布功能,可以打开<Tomcat安装目录>\webapps\axis2\WEB-INF\conf\axis2.xml,找到如下的配置代码:

<parameter name="hotdeployment">true</parameter>

    true改为false即可。要注意的是,Axis2在默认情况下虽然是热发布,但并不是热更新,也就是说,一旦成功发布了WebService,再想更新该WebService,就必须重启Tomcat。这对于开发人员调试WebService非常不方便,因此,在开发WebService时,可以将Axis2设为热更新。在axis2.xml文件中找到<parameter name="hotupdate">false</parameter>,将false改为true即可。

    3. 在浏览器中测试WebService时,如果WebService方法有参数,需要使用URL的请求参数来指定该WebService方法参数的值,请求参数名与方法参数名要一致,例如,要测试getGreeting方法,请求参数名应为name,如上面的URL所示。

    4. 发布WebServicepojo目录只是默认的,如果读者想在其他的目录发布WebService,可以打开axis2.xml文件,并在<axisconfig>元素中添加如下的子元素:

    <deployer extension=".class" directory="my" class="org.apache.axis2.deployment.POJODeployer"/>

    上面的配置允许在<Tomcat安装目录>\webapps\axis2\WEB-INF\my目录中发布WebService。例如,将本例中的SimpleService.class复制到my目录中也可以成功发布(但要删除pojo目录中的SimpleService.class,否则WebService会重名)。

三、 Java实现调用WebService的客户端程序

    WebService是为程序服务的,只在浏览器中访问WebService是没有意义的。因此,在本节使用Java实现了一个控制台程序来调用上一节发布的WebService。调用WebService的客户端代码如下:

package client; import javax.xml.namespace.QName; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; public class RPcclient { public static void main(String[] args) throws Exception { // 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getoptions(); // 指定调用WebService的URL EndpointReference targetEPR = new EndpointReference( "http://localhost:8080/axis2/services/SimpleService"); options.setTo(targetEPR); // 指定getGreeting方法的参数值 Object[] opAddEntryArgs = new Object[] {"超人"}; // 指定getGreeting方法返回值的数据类型的Class对象 Class[] classes = new Class[] {String.class}; // 指定要调用的getGreeting方法及WSDL文件的命名空间 QName opAddEntry = new QName("http://ws.apache.org/axis2","getGreeting"); // 调用getGreeting方法并输出该方法的返回值 System.out.println(serviceClient.invokeBlocking(opAddEntry,opAddEntryArgs,classes)[0]); // 下面是调用getPrice方法的代码,这些代码与调用getGreeting方法的代码类似 classes = new Class[] {int.class}; opAddEntry = new QName("http://ws.apache.org/axis2","getPrice"); System.out.println(serviceClient.invokeBlocking(opAddEntry,new Object[]{},classes)[0]); } }

运行上面的程序后,将在控制台输出如下的信息:

你好 超人
443

 在编写客户端代码时应注意如下几点:

    1. 客户端代码需要引用很多Axis2jar包,如果读者不太清楚要引用哪个jar包,可以在Eclipse的工程中引用Axis2发行包的lib目录中的所有jar包。

    2. 在本例中使用了RPCServiceClient类的invokeBlocking方法调用了WebService中的方法。invokeBlocking方法有三个参数,其中第一个参数的类型是QName对象,表示要调用的方法名;第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}

    3. 如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法,该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。

    4. 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:deFinitions>元素的targetNamespace属性值,下面是SimpleService类生成的WSDL文件的代码片段:

<?xml version="1.0" encoding="UTF-8" ?> - <wsdl:deFinitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:ns="http://ws.apache.org/axis2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://ws.apache.org/axis2"> - <wsdl:types> - <xs:schema attributeFormDefault="qualified" elementFormDefault="unqualified" targetNamespace="http://ws.apache.org/axis2"> - <xs:element name="getPrice"> - <xs:complexType> <xs:sequence /> </xs:complexType> </xs:element> - <xs:element name="getPriceResponse"> - <xs:complexType> - <xs:sequence> <xs:element minOccurs="0" name="return" type="xs:int" /> </xs:sequence> </xs:complexType> </xs:element> - <xs:element name="getGreeting"> - <xs:complexType> - <xs:sequence> <xs:element minOccurs="0" name="name" nillable="true" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> - <xs:element name="getGreetingResponse"> - <xs:complexType> - <xs:sequence> <xs:element minOccurs="0" name="return" nillable="true" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </wsdl:types> + <wsdl:message name="getGreetingRequest"> <wsdl:part name="parameters" element="ns:getGreeting" /> </wsdl:message> - <wsdl:message name="getGreetingResponse"> <wsdl:part name="parameters" element="ns:getGreetingResponse" /> </wsdl:message> - <wsdl:message name="getPriceRequest"> <wsdl:part name="parameters" element="ns:getPrice" /> </wsdl:message> - <wsdl:message name="getPriceResponse"> <wsdl:part name="parameters" element="ns:getPriceResponse" /> </wsdl:message> - <wsdl:portType name="SimpleServicePortType"> - <wsdl:operation name="getGreeting"> <wsdl:input message="ns:getGreetingRequest" wsaw:Action="urn:getGreeting" /> <wsdl:output message="ns:getGreetingResponse" wsaw:Action="urn:getGreetingResponse" /> </wsdl:operation> - <wsdl:operation name="getPrice"> <wsdl:input message="ns:getPriceRequest" wsaw:Action="urn:getPrice" /> <wsdl:output message="ns:getPriceResponse" wsaw:Action="urn:getPriceResponse" /> </wsdl:operation> </wsdl:portType> - <wsdl:binding name="SimpleServiceSoap11Binding" type="ns:SimpleServicePortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> - <wsdl:operation name="getGreeting"> <soap:operation soapAction="urn:getGreeting"/> - <wsdl:input> <soap:body use="literal" /> </wsdl:input> - <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> - <wsdl:operation name="getPrice"> <soap:operation soapAction="urn:getPrice"/> - <wsdl:input> <soap:body use="literal" /> </wsdl:input> - <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> - <wsdl:binding name="SimpleServiceSoap12Binding" type="ns:SimpleServicePortType"> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/> - <wsdl:operation name="getGreeting"> <soap12:operation soapAction="urn:getGreeting"/> - <wsdl:input> <soap12:body use="literal" /> </wsdl:input> - <wsdl:output> <soap12:body use="literal" /> </wsdl:output> </wsdl:operation> - <wsdl:operation name="getPrice"> <soap12:operation soapAction="urn:getPrice"/> - <wsdl:input> <soap12:body use="literal" /> </wsdl:input> - <wsdl:output> <soap12:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> - <wsdl:binding name="SimpleServiceHttpBinding" type="ns:SimpleServicePortType"> <http:binding verb="POST" /> - <wsdl:operation name="getGreeting"> <http:operation location="getGreeting" /> - <wsdl:input> <mime:content type="application/xml" part="parameters" /> </wsdl:input> - <wsdl:output> <mime:content type="application/xml" part="parameters" /> </wsdl:output> </wsdl:operation> - <wsdl:operation name="getPrice"> <http:operation location="getPrice" /> - <wsdl:input> <mime:content type="application/xml" part="parameters" /> </wsdl:input> - <wsdl:output> <mime:content type="application/xml" part="parameters" /> </wsdl:output> </wsdl:operation> </wsdl:binding> - <wsdl:service name="SimpleService"> - <wsdl:port name="SimpleServiceHttpSoap11Endpoint" binding="ns:SimpleServiceSoap11Binding"> <soap:address location="http://localhost:8080/axis2/services/SimpleService.SimpleServiceHttpSoap11Endpoint/" /> </wsdl:port> - <wsdl:port name="SimpleServiceHttpSoap12Endpoint" binding="ns:SimpleServiceSoap12Binding"> <soap12:address location="http://localhost:8080/axis2/services/SimpleService.SimpleServiceHttpSoap12Endpoint/" /> </wsdl:port> - <wsdl:port name="SimpleServiceHttpEndpoint" binding="ns:SimpleServiceHttpBinding"> <http:address location="http://localhost:8080/axis2/services/SimpleService.SimpleServiceHttpEndpoint/" /> </wsdl:port> </wsdl:service> </wsdl:deFinitions>


 

四、用wsdl2java简化客户端的编写

    也许有很多读者会说“有没有搞错啊,只调用两个WebService方法用要写这么多代码,太麻烦了”。

    不过幸好Axis2提供了一个wsdl2java.bat命令可以根据WSDL文件自动产生调用WebService的代码。wsdl2java.bat命令可以在<Axis2安装目录>"bin目录中找到。在使用wsdl2java.bat命令之前需要设置AXIS2_HOME环境变量,该变量值是<Axis2安装目录>。需要注意的是你首先得把jdk的系统变量配置好,因为我们一旦都是在eclipse中开发java程序的,不需要配置jdk的系统变量,一上来就配置axis2的系统变量肯定会找不到jdk的,需要注意的是安装jdk是把jdk和jre要安装在不同的文件夹下面,不然在配置classpath是就会找不到几个jar文件。axis2的系统变量配置与jdk的相同,再次就不在说了,jdk测试的时候可以用javac -version,axis2测试的时候可以用wsdl2java。

把已经生成的wsdl文件转换成java文件的话,就需要在doc敲命令,命令就不介绍了,百度一下就可以了,这里需要强调的是uri而不是url,即使这个错误搞得我浪费了一小时的时间,也不知道当初制定这个命令的人是怎么想的,太坑爹了。更不爽的是,生成的java文件不知道去哪了,搞得我还得搜一下。

       其实这是我的错误,明明人家已经是在当前目录下了,我还没注意到,哎,专业意识需要提高了

这不是清清楚楚的写着C………………吗,我太坑爹了,生成的这个stub类我就不贴出来了,实在是太多了,看了一下有2275行,太恐怖了,不知道为什么会这么多,看来就简洁程度而言,还是xml文件简洁哈。

 

l   其中-url参数指定了wsdl文件的路径,可以是本地路径,也可以是网络路径。-p参数指定了生成的Java类的包名,-o参数指定了生成的一系列文件保存的根目录。在执行完上面的命令后,读者就会发现在当前目录下多了个stub目录,在."stub"src"client目录可以找到一个SimpleServiceStub.java文件,该文件复杂调用WebService,读者可以在程序中直接使用这个类,代码如下:

package client;

public class StubClient {  public static void main(String[] args) throws Exception      {         SimpleServiceStub stub = new SimpleServiceStub();         SimpleServiceStub.GetGreeting gg = new SimpleServiceStub.GetGreeting();         SimpleServiceStub.GetPrice gp = new SimpleServiceStub.GetPrice();         gg.setName("比尔");         System.out.println( stub.getGreeting(gg).get_return());         System.out.println(stub.getPrice(gp).get_return());     }

}


 

         上面的代码大大简化了调用WebService的步骤,并使代码更加简洁。但要注意的是,wsdl2java.bat命令生成的Stub类将WebService方法的参数都封装在了相应的类中,类名为方法名,例如,getGreeting方法的参数都封装在了GetGreeting类中,要想调用getGreeting方法,必须先创建GetGreeting类的对象实例。

       
          这就是今天下午的劳动成果了,虽说是照着教程做的,但是起码我发现了教程的好多错误,自己也从中学到了不少的东西。

         下班了,做梦去!明天继续!

今天关于WebService之--------Axis2准备工作axis2 webservice的讲解已经结束,谢谢您的阅读,如果想了解更多关于Axis2 WebService 客户端 Axis2 调用、Axis2 WebService之会话管理(Session)、axis2实现webservice之使用services.xml文件发布WebService、axis2实现WebService之用POJO实现0配置的WebService的相关知识,请在本站搜索。

本文标签: