Web Service之AXIS(一)

1、Axis 全称是 Apache Extensible Interaction System :阿帕奇可扩展交互系统。是一个开源、基于XML的Web服务框架。包含了Java和C++语言实现的SOAP服务器,以及各种公用服务及API以生成和部署Web服务应用。可创造出可操作的、分布式的计算应用。

 

 开发环境:Myeclipse、Tomcat、jdk、AXis2

首先可以下载如下两个zip包:
axis2-1.7.6-bin.zip
axis2-1.7.6-war.zip
其中 axis2-1.7.6-bin.zip文件中包含了Axis2中所有的jar文件, 
axis2-1.7.6-war.zip文件用于将WebService发布到Web容器中。
将axis2-1.7.6-war.zip文件解压到相应的目录,将目录中的axis2.war文件放到<Tomcat安装目录>\webapps目录中,

并启动Tomcat,在浏览器地址栏中输入如下的URL:

 http://localhost:8080/axis2/

如看到axis2的主页面则安装成功。

将axis2-1.7.6-war.zip压缩包里面的axis2.war包解压到tomcat的webapps目录下,启动tomcat,访问地址http://localhost:8080/axis2/ ,即可访问axis2的Welcome!页面。
访问地址http://localhost:8080/axis2/services/listServices 另可访问服务列表。

http://localhost:8080/axis2/services/Version?method=getVersion  获取版本

使用Axis2方式发布webService的三种方式

1、简单的pojo方式(无需配置):

在Axis2中不需要进行任何的配置,就可以直接将一个简单的POJO发布成WebService。其中POJO中所有的public方法将被发布成WebService方法。
示例代码如下:(这个POJO的类名必须是XXXService格式,否则报错)

将HelloService.class文件放到tomcat\webapps\axis2\WEB-INF\pojo目录中【注:若没有pojo目录,则手动新建该目录】。
在浏览器地址栏中输入如下的URL:
http://127.0.0.1:8080/axis2/services/listServices 即可访问刷新后的服务列表。【注:POJO类不能使用package关键字声明包,若使用axis2管理平台发布,则需要修改HelloService类,去掉package字段。】

 

在浏览器地址栏中输入如下的两个URL来分别测试sayHelloToPerson和sayHello方法:
1.http://localhost:8080/axis2/services/HelloService/sayHello 

 


2.http://localhost:8080/axis2/services/HelloService/sayHelloToPerson?name=huadi

 


【注:发布WebService的pojo目录只是默认的,如果想在其他的目录发布WebService,可以打开axis2/WEB-INF/conf/axis2.xml文件,并在<axisconfig>元素中添加如下的子元素:

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

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


访问 http://127.0.0.1:8080/axis2/services/HelloService?wsdl 即可访问服务UserService的wsdl描述

 

 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方法,参数的值,请求参数名与方法参数名要一致,例如,要测试sayHelloToPerson方法,请求参数名应为name,如上面的URL所示。

2、打jar包的方式:

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

 

package com.axis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class HelloWSDD {
    
    public String getName(String name) {
        return "Welcome " + name;
    }

    public Double getPrice() {
        return Math.random();
    }

    public int getNum() {
        return new Random().nextInt(100);
    }

    public List<String> getList() {
        List<String> list = new ArrayList<String>();
        list.add("num1");
        list.add("num2");
        list.add("num3");
        list.add("num4");
        list.add("num5");
        return list;

    }

    public Map<String, String> getMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("NO.1", "Y1");
        map.put("NO.2", "Y2");
        map.put("NO.3", "Y3");
        map.put("NO.4", "Y4");
        map.put("NO.5", "Y5");
        return map;

    }
}
带package的类

 

问题解决:

信息: Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
        at org.apache.coyote.http11.InternalAprInputBuffer.parseRequestLine(InternalAprInputBuffer.java:238)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1028)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
        at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2555)
        at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2544)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:662)

解决方法:

Plan 1:
更换低版本的Tomcat来规避这种问题。

Plan 2:
在conf/catalina.properties中最后添加一行:

org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

 这个案例整理了半天,才成功。下面讲解一下步骤

1。生成services.xml文档。

<?xml version="1.0" encoding="UTF-8"?>
<service name="HelloWSDDService" targetNamespace="http://ws.apache.org/ax2">
    <schema schemaNamespace="http://sdjxd.com.cn" />
    <description>Web Service实例一</description>
    <parameter name="ServiceClass">com.axis.HelloWSDDService</parameter>
    <messageReceivers>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
            class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
    </messageReceivers>
</service>   
services.xml

2.放置同一目录下

3.cmd命令行运行

4.将生成的aws.aar压缩包放置在tomacta安装目录\webapps\axis2\WEB-INF\services下

5.运行tomact。查看服务

打jar的方式可以借助插件工具:

下载插件http://axis.apache.org/axis2/java/core/download.html

一、new---》other----》Axis

:填写服务器端类的.class文件的地址目录

完成

3、不打jar包的方式:

 

有一个最简单的方法就是把axis2.war中的内容作为Web Project的基础, 来进行开发.

 

不过为了更清楚的了解如何在一个已有的Web Project中嵌入axis2, 那就手动来配置。大致分如下几个步骤:

 

一、新建Web Project,名为“20171030”

 

二、下载axis2-1.6.1-war.zip包,解压缩

 

将axis2/WEB-INF/lib 里的jar包拷贝到 WebServiceDemo/WebRoot/WEB-INF/lib/

 

将axis2.war/axis2-web拷贝至WebServiceDemo/ WebRoot/axis2-web/

 

三、配置axis2 servlet

 

打开WebServiceDemo/WebRoot/WEB-INF/web.xml,增加如下配置:

 

 

 

<servlet>    
    <servlet-name>AxisServlet</servlet-name>    
    <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>    
    <load-on-startup>1</load-on-startup>    
</servlet>         
<servlet-mapping>    
           <servlet-name>AxisServlet</servlet-name>    
           <url-pattern>/services/*</url-pattern>    
</servlet-mapping>  

 

 

 

 四、写一个简单的web服务类

 

 

package com.axis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class HelloWSDDService {
 
 public String getName(String name) {
  return "Welcome " + name;
 }

 public Double getPrice() {
  return Math.random();
 }

 public int getNum() {
  return new Random().nextInt(100);
 }

 public List<String> getList() {
  List<String> list = new ArrayList<String>();
  list.add("num1");
  list.add("num2");
  list.add("num3");
  list.add("num4");
  list.add("num5");
  return list;

 }

 public Map<String, String> getMap() {
  Map<String, String> map = new HashMap<String, String>();
  map.put("NO.1", "Y1");
  map.put("NO.2", "Y2");
  map.put("NO.3", "Y3");
  map.put("NO.4", "Y4");
  map.put("NO.5", "Y5");
  return map;

 }
}

 


 

 

五、配置Web Service.

 

由于axis2已嵌入到20171030项目中,所以web service就不用打包成aar,而是直接在/WEB-INF目录下创建相应的文件夹和services.xml,目录结构如下图:

 

 

 

六、services.xml

<?xml version="1.0" encoding="UTF-8"?>
<service name="HelloWSDDService" targetNamespace="http://ws.apache.org/ax2">
 <schema schemaNamespace="http://sdjxd.com.cn" />
 <description>Web Service实例一</description>
 <parameter name="ServiceClass">com.axis.HelloWSDDService</parameter>
 <messageReceivers>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
   class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
   class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
 </messageReceivers>
</service>

七、在浏览器中访问http://localhost:8080/20171030/services/listServices

 

可以看到myService服务,说明服务已部署成功

 

       输入http://localhost:8080/20171030/services/HelloWSDDService?wsdl

 

    可以查看到该Web服务的描述文件

 

以上是Axis2的发布方式,你查看资料也会发现将.java转变成.jws进行发布的。这里要说明一下。Axis1和Axis2发布方式是有所不同的,希望大家不要混淆。这里我也给出axis-1_4的发布方式。

环境 tomcat、myeclipse、axis-1_4

 下载地址: http://www.apache.org/dist/axis/axis/java/1.4/

解压axis-bin-1_4.zip。进入axis-1_4\webapps目录下。复制文件夹axis到Tomact的webapps目录下。启动Tomcat,在浏览器测试一下Axis是否成功,如出现如下页面表示成功。地址:http://localhost:8080/axis

1、即时发布

①、将java文件扩展名.java重命名为.jws文件,并放在Web应用程序的根目录下,如下所示:

 

②、在浏览器中运行http://localhost:8080/axis/HelloService.jws,出现下面界面:

点击链接,可查看wsdl文件

 

测试代码,编写客户端:

public class CallService {
    public static void main(String[] args) {
        // 请求地址 指明服务所在位置
        String url = "http://localhost:8080/axis/HelloService.jws";
        // 创建服务 创建一个Service实例,注意是必须的!
        Service service = new Service();
        try {
            // 调用服务 创建Call实例,也是必须的!
            Call call = (Call) service.createCall();
            // 服务地址 为Call 设置服务的位置
            call.setTargetEndpointAddress(url);
            // 请求方法 注意方法名与 HelloWorld.java中一样
            call.setOperationName(new QName(url, "sayHelloToPerson"));
            // 执行调用
            String result = (String) call.invoke(new Object[] { "huadiyatou" });
            System.out.println(result);

            // 请求方法
            call.setOperationName(new QName(url, "sayHello"));
            // 执行调用
            String result1 = (String) call.invoke(new Object[] {});
            System.out.println(result1);
        } catch (ServiceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

结果如下,即时发布完成。

即时发布的特点:只能使用原始数据类型和非常普通的Java类如Date,作为方法参数和返回类型,不能使用自定义的类。不支持带package包的出现

2、定制发布(WSDD :Web Service Deployment Descriptor)

步骤一、编写服务器端代码,并编译该程序

package com.axis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class HelloWSDD {
    public String getName(String name) {
        return "Welcome " + name;
    }

    public Double getPrice() {
        return Math.random();
    }

    public int getNum() {
        return new Random().nextInt(100);
    }

    public List<String> getList() {
        List<String> list = new ArrayList<String>();
        list.add("num1");
        list.add("num2");
        list.add("num3");
        list.add("num4");
        list.add("num5");
        return list;

    }

    public Map<String, String> getMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("NO.1", "Y1");
        map.put("NO.2", "Y2");
        map.put("NO.3", "Y3");
        map.put("NO.4", "Y4");
        map.put("NO.5", "Y5");
        return map;

    }
}
服务器端代码

 步骤二、把编译后的文件(带包路径)拷贝到 (本地服务器)apache-tomcat-7.0.42\webapps\axis\WEB-INF\classes下

步骤三、编写发布文件.wsdd,并复制到tomact的webapps\axis\WEB-INF目录下,通常命名为deploy.wsdd,即SOAP服务发布描述文件


<!-- deployment元素:指定wsdd所用的XML名字空间。deployment是其根元素,可以定义多个Service元素 -->


<
deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <!-- Services from VisualWebService WSDL service -->  

<!-- service元素:定义一项SOAP服务,他有name和provider两个属性,name代表这项服务的唯一标示符,即服务的名字。SOAP 会根据name属性访问该SOAP服务,provider指定了实现这项服务的语言及服务方式。-->
  <service name="HelloWS" provider="java:RPC">
    <!--parameter元素:包含name和value属性,如果name值为className,则指定该服务的类名,如果name为allowedMethods,则指定该项服务包含的方法-->
<parameter name="className" value="com.axis.HelloWSDD"/> <!--接口文件位置--> <parameter name="allowedMethods" value="*"/> </service> </deployment>

步骤四、控制台,进入目录F:\apache-tomcat-7.0.82\webapps\axis\WEB-INF下。键入:java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient wsdd全名,一般wsdd的名字为deploy.wsdd(注:服务器Tomcat必须已经启动)

你会发现目录下多了一个server-config.wsdd文件,这就是AXIS的配置文件,以后所有的服务发布描述都会在里面找到。(当然,你可以直接修改它,不用再写deploy.wsdd。但server-config.wsdd文件应该存放在apache-tomcat-7.0.42\webapps\axis\WEB-INF 下)

得到结果<Admin>Doneprocessing</Admin>表示部署成功。或者查看 http://localhost:8080/axis/servlet/AxisServlet 是否发布成功

步骤五、

浏览器访问:http://localhost:8080/axis/services/HelloWS?method=getName&name=hahaha

java程序访问:

package com.axis;

import java.rmi.RemoteException;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class CallHelloWSDD {
    public static void main(String[] args) {
        // 请求地址
        String url = "http://localhost:8080/axis/services/HelloWS";
        // 创建服务
        Service service = new Service();
        try {
            // 调用服务
            Call call = (Call) service.createCall();
            // 服务地址
            call.setTargetEndpointAddress(url);
            // 请求方法
            call.setOperationName(new QName(url, "getName"));
            // 执行调用
            String result = (String) call.invoke(new Object[] { "Mswangg" });
            System.out.println(result);
            // 请求方法
            call.setOperationName(new QName(url, "getPrice"));
            // 执行调用
            double result1 = (Double) call.invoke(new Object[] {});
            System.out.println(result1);
            // 请求方法
            call.setOperationName(new QName(url, "getNum"));
            // 执行调用
            int result2 = (Integer) call.invoke(new Object[] {});
            System.out.println(result2);
            // 请求方法
            call.setOperationName(new QName(url, "getList"));
            // 执行调用
            Object result3 = call.invoke(new Object[] {});
            System.out.println(result3);
            System.out.println("***********************");
            // 请求方法
            call.setOperationName(new QName(url, "getMap"));
            // 执行调用
            Map<String, String> result4 = (Map<String, String>) call
                    .invoke(new Object[] {});
            for (Entry<String, String> e : result4.entrySet()) {
                System.out.println(e.getKey() + ":" + e.getValue());
            }
        } catch (ServiceException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
测试代码

 即时发布和定制发布的客户端代码区别在于:

即时发布:String url = "http://localhost:8080/axis/HelloService.jws";

定制发布:String url = "http://localhost:8080/axis/services/HelloWS";

posted @ 2017-10-30 15:34  花娣丫头小愤青  阅读(844)  评论(0编辑  收藏  举报