科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道SOAP净化有线协议(四):简化客户程序2

SOAP净化有线协议(四):简化客户程序2

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

 Java 2平台1.3版本为Java映像API(Reflection API)增加了一个极其实用的扩展:动态代理类。一个动态代理类就是一个实现了一系列运行时指定的接口的类。这个代理可以象它真正实现了这些接口一样使用。

来源:IT专家网 2008年5月12日

关键字: 协议 净化 SOAP java

  • 评论
  • 分享微博
  • 分享邮件
 现在要做的是为远程服务调用设置参数。为此,我们要用到invoke()方法的第三个参数:传入动态代理上被调用方法的一个参数数组。数组中索引为0的参数是方法调用中最左边的参数,索引为1的参数是方法的第二个参数,依此类推。举例来说,如果客户程序调用了sayHelloTo(String name)方法,那么参数数组就是包含一个字符串的数组。invoke()方法处理该数组的每一个元素,创建一个由Parameter对象构成的向量(Vector)(正如第二篇文章中客户程序所做的那样):

java.util.Vector params = new java.util.Vector();
for( int i=0; i<args.length; i++ )
{
if( isSimple(args[i]) || isSimpleArray(args[i]) )
{
params.add(new Parameter(_paramName+(i+1),
args[i].getClass(),args[i],null));
}
else if( isVector(args[i]) )
{
addMapping((java.util.Vector)args[i]);
params.add(new
Parameter(_paramName+(i+1),args[i].getClass(),args[i],null));
}
// 如果这个数组的元素不属于Java基本数据类型
// 则假定这是一个JavaBean的数组
else if( isArray(args[i]) )
{
if( smr == null )
smr = new SOAPMappingRegistry();
if( beanSer == null )
beanSer = new BeanSerializer();
ArraySerializer arraySer = new ArraySerializer();
smr.mapTypes(Constants.NS_URI_SOAP_ENC,
null, null, beanSer, beanSer);
smr.mapTypes(Constants.NS_URI_SOAP_ENC,
null,args[i].getClass(), arraySer, arraySer);
params.add(new Parameter(_paramName+(i+1),
args[i].getClass(),args[i],null));
}
// 假定这是一个Bean
else
{
if( smr == null )
smr = new SOAPMappingRegistry();
if( beanSer == null )
beanSer = new BeanSerializer();
String qnamePart = args[i].getClass().getName();
smr.mapTypes(Constants.NS_URI_SOAP_ENC,
new QName(urn, qnamePart),args[i].getClass(), beanSer,
beanSer);
params.add(new Parameter(_paramName+(i+1),args[i].getClass(),args[i],null));
}
}

  invoke()方法用到了许多私有的辅助方法,比如用isSimple()来确定参数的类型。如果参数是一个JavaBean或者一个数组,那么,程序必须设置一个定制的SOAP映射注册项,并通过setSOAPMappingRegistry()方法对Call对象作相应的设置(参见第二篇文章)。SOAP代理假定,当出现JavaBean时,SOAP服务用到的所有JavaBean按照如下方式映射:NameSpace URI设置成对象ID,Local Part设置成JavaBean完整的类名。我们部署HelloWorld服务时正是按照这个要求进行,所以一切都不存在问题。

  invoke()方法的剩余部分相当简单:设置Call对象参数,设置定制SOAP映射注册项(如果有必要的话),发出调用,接收方法调用的返回值。如下所示:

if( params.size() != 0 )
call.setParams(params);
if( smr != null )
call.setSOAPMappingRegistry(smr);
// 发出调用
Response resp = call.invoke(serverURL, "");
if( !resp.generatedFault() )
{
Parameter ret = resp.getReturnValue();
return(ret.getValue());
}
else
{
Fault fault = resp.getFault();
throw new
SOAPException(fault.getFaultCode(),fault.getFaultString());
}

 二、HelloWorld服务

  下面是HelloWorld服务的完整代码。有似曾相识的感觉吗?

package hello;
public class HelloServer
{
public String sayHelloTo(String name)
{
System.out.println("sayHelloTo(String name)");
return "Hello " + name + ", How are you doing?";
}
public String sayHelloTo(Name theName)
{
System.out.println("sayHelloTo(Name theName)");
return "Hello " + theName.getName() + ", How are you doing?";
}
}

  回忆一下,Name是一个简单的JavaBean,代码如下:

package hello;
public class Name
{
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}

  事实上,这里服务的代码与第二篇文章中的服务程序代码完全一样。对于服务开发者来说,唯一增加的工作是创建Java接口。部署服务的方法也和第二篇文章中讨论的完全一样,所以这里我不再介绍。相同的地方还不止如此,编译和运行客户程序的方法也和第二篇文章介绍的一样。为什么有这么多相同之处呢?因为我们创建的代理是一个非插入式的框架,它不会修改和干涉任何Apache SOAP部件的内部工作——无论是客户端还是服务端。

  三、其他说明

  本文讨论的SOAP代理(可以从文章后面下载)支持以下参数类型:

  ⑴ 下面的Java基本数据类型及其对应的对象形式。

boolean, Boolean,
double, Double,
float, Float,
long, Long,
int, Integer,
short, Short,
byte, Byte

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章