[转贴]用Axis和SOAP开发基于JAX-RPC的Web服务

来源:互联网 发布:淘宝店 出售 编辑:程序博客网 时间:2024/05/11 12:11
1. Web服务示例:订单处理
  我之所以选择“订单处理”作为示例,是因为它比较接近实际的商业用例。该Web服务能够处 理,更新一个给定的订单。为了达到这个目的,它必须具有两个方法:processOrder和updateOrder。方法processOrder具有 一个IN参数orderID和一个作为OUT参数的Order(订单)对象。processOrder方法返回一个状态字符串。方法 updateOrder把一个Order(订单)对象作为INOUT参数,它更新orderDate,并且把Order对象返回给客户端。由于这两个方法 都用到了一个复杂数据类型Order,更确切的说,它被用作为OUT/INOUT参数,所以需要开发一个Holder类。下面的清单1和清单2分别给出了 Order类和相应的Holder类(为了说明,全部代码都放在sample包中):
  清单1:Order类
  package sample;
  public class Order {
   // ID for order
   private String orderID = null;
  
   // date of order
   private String orderDate= null;
  
   // getter methodspublic String getOrderID() {
   return orderID;
   }
   public String getOrderID() {
   return orderID;
   }
   // setter methods
   public void setOrderID(String orderID) {
   this.orderID = orderID;
   } public void setOrderDate(String orderDate) {
   this. orderDate = orderDate;
   }
  }
  
  清单2:Order类相应的Holder类
  
  // Note that holder class is in the holders package and its name
  // is derived by adding Holder as a suffix to 'Order', as per
  // the JAX-RPC specification.
  package sample.holders;
  
  public class OrderHolder {
   // Order's object
   public Order value = null;
  
   // default constructor
   public void OrderHolder () { }
  
   // constructor, which takes value as a parameter
   public void OrderHolder (Order value) {
   this.value=value;
   }
  }
  
  现在,我们来开发具有上述功能的Web服务。清单3给出了相应的代码。
  清单3:订单处理Web服务
  package sample;
  public class OrderProcessingService {
   // Method 1: processes a order given ID as input and
   // return status and Order object as an OUT parameter
   public String processOrder(String orderID,
   OrderHolder orderHolder ) {
   String status = "pending";
   // perform business logic here
   // for simplicity just filling the Order object
   Order order = new Order();
   order.setOrderID(orderID);
   order.setOrderDate("03 March 2003");
  
   // set the Holder value to the order.
   orderHolder.value = order;
   //set the status
   status = "complete" ;
   return status;
   }
   // Method 2: updates a order given Order as an INOUT
   // parameter and returns status.
   public String updateOrder(OrderHolder orderHolder) {
   String status = "pending";
   // perform update here
   Order order = orderHolder.value;
   order.setOrderDate("03 April 2003");
  
   // Note that orderID is not changed.
   // It will be same as the passed one.
  
   // set the Holder value to the order.
   orderHolder.value = order;
   //set the status
   status = "complete" ;
   return status;
   }
  }
  至此,我们已经完成Web服务的开发,下一步就是编译,把它部署到Tomcat-Axis平台上去。编译后,我们需要用部署描述文件把上述的Web服务部署到Tomcat-Axis。
  清单4:部署文件deploy.wsdd
  <deployment xmlns="http://xml.apache.org/axis/wsdd/"
   xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  
  <service name=" OrderProcessingService" provider="java:RPC">
   <parameter name="className"
   value="sample.OrderProcessingService "/>
   <parameter name="allowedMethods" value="*"/>
   <operation name="processOrder">
   <parameter name="arg1" mode="IN"/>
   <parameter name="arg2" mode="OUT"/>
   </operation>
   <operation name="updateOrder">
   <parameter name="arg1" mode="INOUT"/>
   </operation>
  </service>
  </deployment>
  
    上述的部署描述文件实际上是让服务器知道有关该Web服务的一些信息,例如公开的方法,期望的参数以及返回值类型等。部署 OrderProcessingService,我们需要传递参数“deploy.wsdd”,调用Axis admin服务。运行在同一服务器上的admin服务将处理描述文件,部署该Web服务,至此,它可以被客户端调用了。
   在与deploy.wsdd文件相同的目录下运行下列命令:
  java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient
  -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd
  
  其中,AXISCLASSPATH用于设置Axis环境(详情请参考axis installation guide)。
  可以通过下面的地址来访问OrderProcessing服务:http://<your_machine_name>:<port-num>/<contextURI>/<serviceURI>.
  对我们的示例来说,地址如下:
  http://localhost:8080/axis/services/OrderProcessing
  
  2. Web服务OrderProcessing的客户端
  动态客户端
  动态客户端类似于用反射APIs(reflection APIs)查找,调用Java类的方法.
  这里,所有的信息,例如目标端点(target endpoint),方法参数等等都必须明确的设定。清单5所列出的代码展示了怎样编写一个调用Web服务OrderProcessing的updateOrder方法的动态客户端。
  
  清单5:动态客户端
  package sample.client;
  import org.apache.axis.client.Call;
  import org.apache.axis.client.Service;
  import org.apache.axis.encoding.XMLType;
  import javax.xml.rpc.ParameterMode;
  import javax.xml.rpc.encoding.*;
  import javax.xml.namespace.QName;
  import java.util.*;
  import sample.*;
  
  /**
   * This class illustrates how to use the JAX-RPC API to invoke
   * the Order Processing Web service dynamically
   */
  public class DynamicClient {
   public static void main(String[] args) throws Exception {
  
  
   // create service factory
   ServiceFactory factory = ServiceFactory.newInstance();
  
   // define qnames
   String targetNamespace = "OrderProcessingService";
  
   QName serviceName = new QName(targetNamespace,
   "OrderProcessingService");
  
   QName portName = new QName(targetNamespace,
   "OrderProcessingService");
   QName operationName = new QName(targetNamespace, "updateOrder");
  
   // create service
   Service service = new Service();
   Call call = (Call) service.createCall();
   Qname qn = new Qname(targetNamespace, "OrderHolder");
  
   call.registerTypeMapping(OrderHolder.class, qn,
   new org.apache.axis.encoding.ser.BeanSerializerFactory
   (OrderHolder.class, qn),
   new org.apache.axis.encoding.ser.BeanDeserializerFactory
   (TicketHolder.class, qn));
  
   // set port and operation name
   call.setPortTypeName(portName);
   call.setOperationName(operationName);
  
   // add parameters
   call.addParameter( "arg1", serviceName, ParameterMode.INOUT );
   call.setReturnType( XMLType.XSD_STRING );
  
   Order order = new Order ();
   order.setOrderID("Order001");
   order.setOrderDate("03 March 2003");
  
  
   // set end point address
   call.setTargetEndpointAddress(
   "http://localhost:8080/axis/services/OrderProcessing");
  
   // Invoke the WebService
   String result = (String) call.invoke( new Object[] { order } );
   System.out.println("result : " +result);
  
   Map outparams = call.getOutputParams();
  
   System.out.println("Got the outparams");
  
  
  }
  
  3. 运行客户端
  用下列命令运行客户端:
  <Prompt>java -cp %AXISCLASSPATH% sample.client.DynamicClient
  结果如下:
  得到输出参数(如在开发客户端时所提到的一样)。
  
  4. 结论
   本文试图揭开Web服务的神秘面纱,表达一种使用Apache开放源代码的Axis工具开发基于JAX-RPC的Web服务是多么的简单和经济适用。该 文还详细阐述了一种“怎样开发”基于JAX-RPC的Web服务的方式。这种开发方式给开发者充分的自由去编写Web服务和客户端,隐藏了以有线XML (on-the-wire XML)格式序列化对象的所有复杂细节。对开发人员来说,它看起来只不过是Java方法调用。本文系列的下一部分,我将讲解Web服务的其他方法和技术。
  5. 参考资料
  l http://jakarta.apache.org/tomcat/index.html
  l http://ws.apache.org/axis/
  l http://java.sun.com/xml/jaxrpc

原贴地址http://www.wangchao.net.cn/bbsshowlist.jsp?bbspages=1&area_id=02&board_id=01&parent_id=31369
原创粉丝点击