用Axis和SOAP开发基于JAX-RPC的Web服务(2)

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

1.         Web服务示例:订单处理

我之所以选择“订单处理”作为示例,是因为它比较接近实际的商业用例。该Web服务能够处理,更新一个给定的订单。为了达到这个目的,它必须具有两个方法:processOrderupdateOrder。方法processOrder具有一个IN参数orderID和一个作为OUT参数的Order(订单)对象。processOrder方法返回一个状态字符串。方法updateOrder把一个Order(订单)对象作为INOUT参数,它更新orderDate,并且把Order对象返回给客户端。由于这两个方法都用到了一个复杂数据类型Order,更确切的说,它被用作为OUT/INOUT参数,所以需要开发一个Holder类。下面的清单1和清单2分别给出了Order类和相应的Holder类(为了说明,全部代码都放在sample包中):

清单1Order 
       
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;
  }
}

 

清单2Order类相应的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/" target=new>Axis installation guide)。

可以通过下面的地址来访问OrderProcessing服务http://<your_machine_name>:<port-num>/<contextURI>/<serviceURI>.

对我们的示例来说,地址如下:

Axis/services/OrderProcessing">http://localhost:8080/Axis/services/OrderProcessing

 

2.         Web服务OrderProcessing的客户端

动态客户端

动态客户端类似于用反射APIsreflection APIs)查找,调用Java类的方法.

这里,所有的信息,例如目标端点(target endpoint),方法参数等等都必须明确的设定。清单5所列出的代码展示了怎样编写一个调用Web服务OrderProcessingupdateOrder方法的动态客户端。

 

清单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-RPCWeb服务是多么的简单和经济适用。该文还详细阐述了一种“怎样开发”基于JAX-RPCWeb服务的方式。这种开发方式给开发者充分的自由去编写Web服务和客户端,隐藏了以有线XMLon-the-wire XML)格式序列化对象的所有复杂细节。对开发人员来说,它看起来只不过是Java方法调用。本文系列的下一部分,我将讲解Web服务的其他方法和技术。

5.         参考资料

l         http://jakarta.apache.org/tomcat/index.html

l         Axis/" target=new>http://ws.apache.org/Axis/

l         JAXRPC" target=new>http://java.sun.com/xml/JAXRPC

 

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值