Axis 1.X 入门实例

来源:互联网 发布:华为交换机端口应用acl 编辑:程序博客网 时间:2024/05/01 07:25

 AXIS是开源的WS运行引擎,是SOAP协议的一个实现。来源于Apache的一个开源项目Apache SOAP.分为1.X 和2.X.两个的体系结构和使用上有较大的区别。 1。X更加稳定一些。它提供了两种发布方式: 即时发布 与 定制发布.

 

(1)下载与安装

  下载地址:http://www.apache.org/dyn/closer.cgi/ws/axis/1_4.  如下载axis-bin-1_4.rar

  Axis安装要求必须先安装web服务器. 此处采用apache-tomcat-6.0.29. 将axis-bin-1_4.rar解压,将webapps下的axis目录拷贝到tomcat 的webapps下. 启动tomcat后,访问 http://localhost:8888/axis/ , 打开页面后点击 Validation 超级链接, 查看"Needed Components"和"Optional Components"下,是否有提示缺少包. 有则根据后边相应的地址下载后,再拷到 axis的lib目录下.  axis首页见下图:

 

  (2)开发WebService 之即时发布

   开发者将JAVA源文件的扩展名改为jws拷贝到%TOMCAT-HOME%/webapps/axis/下即可完成所有发布工作。AXIS的编译引擎会处理接下来的所有事情。

   服务端:(注意类不能带包名)

public class HiHelloJWS {
 
 public String hiHello( String name ) {
  
  String result = " Hi.. " + name + "!";
  System.out.println( result );
  return result;
 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  HiHelloJWS jws = new HiHelloJWS();
  jws.hiHello( "axis1.4" );
 }
}

扩展名改为jws后拷到axis/webapps下。重启TOMCAT后访问http://localhost:8888/axis/HiHelloJWS.jws。点击

Click to see the WSDL 可以看WSDL文档,代发布成功。

 

  客户端:

import javax.xml.namespace.QName;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

 

 

public class ClientHiHelloJWS {


 public static void main(String[] args) {

  try{
   
   String url = "http://localhost:8888/axis/HiHelloJWS.jws";
   Service service = new Service();
   Call call = (Call)service.createCall();
   call.setTargetEndpointAddress( url );
   call.setOperationName( new QName( url, "hiHello" ) );
   String result = (String) call.invoke( new Object[]{ "axis1.4" } );
   System.out.println( result );
  } catch( Exception e ) {
   e.printStackTrace();
  }
 }

}
运行结果:

 Hi.. axis1.4!

这种方式虽简单但牺牲了灵活性。 如果手里只有.class 或jar包,JWS也不能满足你的要求。最痛苦的是不支持发布带包路径的类。故这种方式不实用。

 

  (3)定制发布(WSDD):定制发布需要你编写一个WSDD,在实际开中的不二选择。

 

    服务端: 将HiHelloWSDD.class 拷贝到/%TOMCAT_HOME%/webapps/axisWs/WEB-INF/classes/axis/wsdd/下

package axis.wsdd;

 

public class HiHelloWSDD {
 
 public String hiHello( String name ) {
  
  String result = " Hi.. " + name + "!";
  System.out.println( result );
  return result;
 }
 
 public Integer add( Integer num1, Integer num2 ) {
  
  System.out.print( " num1 = " + num1 + " , num2 = " + num2 + ". " );
  System.out.println( " num1 + num2 = " + ( num1.intValue() + num2.intValue() ) );
  return  new Integer( num1.intValue() + num2.intValue() );
 }
}

 

    发布文件deploy.wsdd: 拷贝到/%TOMCAT_HOME%/webapps/axisWs/WEB-INF/下

 <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http:xml.apache.org/axis/wsdd/providers/java">

<!-- name为服务名; provider为服务类型: RPC, Document, Wrapped,Message -->
 <service name="HiHelloWSDD" provider="java:RPC">
  <parameter name="className" value="axis.wsdd.HiHelloWSDD"/>

<!-- *代表所有方法; 指定具体方法时多个以英文逗号隔开. 如:method1,method2 -->
  <parameter name="allowedMethods" value="*"/>

<!-- scope: request为每个SOAP请求产生一个服务对象;session 为每一个客户;application 程序只会产生一个服务对象 -->
  <parameter name="scope" value="request"/>
 </service>
</deployment>

 

用cmd进入 /%TOMCAT_HOME%/webapps/axisWs/WEB-INF/ 下执行如下命令:

java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8888/axis/servlet/AxisServlet deploy.wsdd

提示如下两行信息代表发布成功.并会同级目录下生成“server-config.wsdd”。通过http://localhost:8888/axis/servlet/AxisServlet 可查看所有的定制服务。

Processing file deploy.wsdd
<Admin>Done processing</Admin>

 

   客户端:

package axis.wsdd;
import javax.xml.namespace.QName;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

 

public class ClientHiHelloWSDD {


 public static void main(String[] args) {

  try{
   String endpoint = "http://localhost:8888/axis/services/HiHelloWSDD";   //这儿与JWS不同
         Service service = new Service();
         Call    call    = (Call) service.createCall();
         call.setTargetEndpointAddress( new java.net.URL( endpoint ) );
         call.setOperationName( "hiHello" );
         String res = (String) call.invoke(new Object[]{ "axis1.4" });
         System.out.println( res );
        
         call.setOperationName( new QName( endpoint, "add" ) );
         Integer iRes = (Integer)call.invoke( new Object[] { new Integer( 8 ), new Integer( 8 ) } );
         System.out.println( iRes );
  } catch( Exception e ) {
   e.printStackTrace();
  }
 }

}

执行输出:

 Hi.. axis1.4!
16


取消发布的WebService:

编写undeploy.wsdd内容如下:

<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
 <service name="HiHelloWSDD" />
</undeployment>

执行命令即可:java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8888/axis/servlet/AxisServlet undeploy.wsdd

 

 (4)Handler: Java EE Web 服务中的Handler技术特点非常像Servlet技术中的Filter。

在Servlet中,当一个HTTP到达服务端时,往往要经过多个Filter对请求进行过滤,然后才到达提供服务的Servlet,这些Filter的功能往往是对请求进行统一编码,对用户进行认证,把用户的访问写入系统日志等。

Web服务中的Handler通常也提供一下的功能:
对客户端进行认证、授权;
把用户的访问写入系统日志;
对请求的SOAP消息进行加密,解密;
为Web Services对象做缓存。

SOAP消息Handler能够访问代表RPC请求或者响应的SOAP消息。在JAX-RPC技术中,SOAP消息Handler可以部署在服务端,也可以在客户端使用。

实现Handler,可以实现org.apache.axis.Handle接口。也可以继承org.apache.axis.handlers. BasicHandler。

BasicHandler中的(MessageContext msgContext)方法是Handler实现类必须实现的方法,它通过MessageContext来获得请求或者响应的SOAPMessage对象,然后对SOAPMessage进行处理。

服务端:

package axis.handler;

 

public class HiHelloWorld {
 
 public String hiHello( String name ) {
  
  String result = " Hi,Hello World. " + name + "!";
  System.out.println( result );
  return result;
 }
}

 

Handler:
package axis.handler;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Date;
import org.apache.axis.AxisFault;
import org.apache.axis.Handler;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;

 

public class CounterHandler extends BasicHandler {

 public void invoke(MessageContext msgContext) throws AxisFault {
  
     try {
         Handler handler = msgContext.getService();
         String info = (String)getOption("testInfo");
         System.out.println( info );
        
         Integer counter = (Integer)handler.getOption("accesses");
         if (counter == null) {
          counter = new Integer(0);
         }
         counter = new Integer(counter.intValue() + 1);
         handler.setOption("accesses", counter);
        
         Date date = new Date();
         String result = date + ": Web 服务 " + msgContext.getTargetService() + " 第" + counter + " 次被调用.";
         System.out.println( result );           
     } catch (Exception e) {
         throw AxisFault.makeFault(e);
     }
 }
}

deploy_handler.wsdd:

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <service name="HiHelloWorld" provider="java:RPC">
  <parameter name="className" value="axis.handler.HiHelloWorld"/>
  <parameter name="allowedMethods" value="*"/>
  <parameter name="scope" value="request"/>
  <requestFlow>
            <handler name="counterHandler" type="java:axis.handler.CounterHandler">
                <parameter name="testInfo" value="Good luck!"/>
            </handler>
        </requestFlow>
 </service>
</deployment>

 

也可以象如下这样写:

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <handler name="counterHandler" type="java:axis.handler.CounterHandler">
        <parameter name="testInfo" value="Good luck!"/>
    </handler>
 <service name="HiHelloWorld" provider="java:RPC">
  <parameter name="className" value="axis.handler.HiHelloWorld"/>
  <parameter name="allowedMethods" value="*"/>
  <parameter name="scope" value="request"/>
  <requestFlow>
            <handler name="counterHandler"/>
        </requestFlow>
 </service>
</deployment>

 

客户端:

package axis.handler;

import javax.xml.namespace.QName;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

 

public class ClientCounterHandler {

 /**
  * @param args
  */
 public static void main(String[] args) {
  
  try{
   String endpoint = "http://localhost:8888/axis/services/HiHelloWorld";

         Service service = new Service();
         Call    call    = (Call) service.createCall();
         call.setTargetEndpointAddress( new java.net.URL( endpoint ) );
         call.setOperationName( "hiHello" );
         String res = (String) call.invoke(new Object[]{ "axis1.4" });
         System.out.println( res );
  } catch( Exception e ) {
   e.printStackTrace();
  }
 }

}

(5)传递JAVA BEAN: (转)

你可以传递自定义的JAVA类,但那样你必须自己创建专门的XML序列化器和反序列化器。而对JavaBean,AXIS提供了现成的序列化器。

 服务端:

package anni;
public class Order {
    private String id;
    private String name;
    public void setId(String id) {
        this.id=id;
    }
    public String getId() {
        return id;
    }
    public void setName(String name) {
        this.name=name;
    }
    public String getName() {
        return name;
    }
}OrderService.java

package anni;
public class OrderService {
    public Order returnOrder(Order order) {
        Order newOrder = new Order();
        if(order.getId().equals("1"))
            newOrder.setName("lingo");
        else newOrder.setName("anni");
        return newOrder;
    }
}

deploy.wsdd:

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    <service name="OrderService" provider="java:RPC">
        <parameter name="allowedMethods" value="returnOrder"/>
        <parameter name="className" value="anni.OrderService"/>
        <beanMapping languageSpecificType="java:anni.Order" qname="ns1:Order"
            xmlns:ns1="urn:BeanService"/>
    </service>
</deployment>

 

客户端:

 客户端也需要Order.java

package anni;
import java.net.*;
import javax.xml.namespace.*;
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;

public class OrderClient {
    public static void main(String args[]) throws Exception {
        Order order = new Order(); // JavaBean
        order.setId("1");
        String endpoint = "http://localhost:8080/axis/services/order"; 

        Service service = new Service();
        Call call = (Call) service.createCall();
        // 注册JavaBean,注意和server-config.wsdd中的配置代码比较
        QName qn = new QName("urn:BeanService", "order");
        call.registerTypeMapping(Order.class, qn, new BeanSerializerFactory(
                Order.class, qn), new BeanDeserializerFactory(Order.class, qn));
        String name = "no!";
        try {
            call.setTargetEndpointAddress(new URL(endpoint));
            // 调用的服务器端方法
            call.setOperationName(new QName("order", "returnOrder"));
            // 设定传入的参数,这里qn即Order.class
            call.addParameter("arg1", qn, ParameterMode.IN);
            // 设定返回的参数是Order.class
            call.setReturnType(qn, Order.class);
            Order result = (Order) call.invoke(new Object[] { order });
            if (result != null)
                name = result.getName();
        } catch (Exception ex) {
            //System.err.println(ex);
        }
        System.out.println(name);
    }
}