slice2java编译Printer.ice生成文件说明

参考《Ice 分布式程序设计》 马维达 译冯立彬的博客

一、Ice文件定义

    Printer.ice文件内容如下:

module demo {

interface Printer {

void printString(string s);

};

};

   在命令行终端,进入到Printer.ice文件所在的目录,使用如下命令编译ice文件:slice2java printer.ice会在目录下面生成一个demo文件夹,里面生成一些java文件,如下图示:

二、类图结构

    这些文件的类图结构如下:

——————————————————————————————————————————

  

三、文件说明

    这里对生成的一些文件做些解释,分两两部份,服务端类文件及客户端类文件:

1. 服务器文件

<interface-name>.java
这个源文件声明在ICE文件中定的接口名称的Java接口,如这里是Printer。

_<interface-name>Operations.java

_<interface-name>OperationsNC.java

这两个接口文件都会被接口文件_<interface-name>.java继承。
    这是两个定义操作的接口文件,每个接口文件中定义了一个操作实现,定义的操作与Slice接口中定义的操作相一致_PrinterOperationsNC中操作:void printString(String s),只是在_<interface-name>Operations.java中定义的方法多了一个参数“Ice.Current __current”_PrinterOperations中的操作:void printString(String s, Ice.Current __current),这个参数的作用是可以允许我们访问 “正在执行的请求”和 “服务器中的操作的实现”等信息,通过它可以访问如下对象:

1、adapter

    通过adapter 成员,你可以访问负责分派当前请求的对象适配器。通过适配器,你又可以访问它的通信器(通过getCommunicator 操作)。

2、id

    id 成员提供当前请求的对象标识。如:

Ice.Current c

Ice.Identity idCopy = new Ice.Identity();//new一个对象标示符idCopy对象

idCopy.name = c.id.name;//通过Current获取当前请求的servant对象标示符的name

idCopy.category = c.id.category;//对象标示符的category

    

    每个Ice 对象都有一个唯一的对象标识。对象标识是用于把一个对象与其他所有对象区别开来的标识值。Ice 对象模型假定对象标识是全局唯一的,也就是说,在一个Ice 通信域中,不会有两个对象具有相同的对象标识。对象标示Identity只有两个成员,name和category成员。

3、facet

    通过facet 成员,你可以访问请求的facet 。

4、operation

    operation 成员含有正在被调用的操作的名字。注意,这个操作名可

能是Ice::Object上的操作的名字,比如ice_ping 或ice_isA。如:

public class PrinterI extends _PrinterDisp {

    public void printString(String s, Ice.Current current) {

        System.out.println(current.operation);

    }

}//输出结果:printString

5、mode

    mode 成员含有操作的调用模式(Normal、Idempotent,或Nonmutating)。

6、ctx

    ctx 成员含有这个调用的当前上下文上下文就是一系列名- 值对如果客户在上下文中放入一些名- 值对,并在发出调用时使用这个上下文,服务器就将能使用客户所发送的这些名- 值对。

在服务器端,操作的实现可以通过Ice.Current 的ctx 成员访问接收到的Context ,并提取客户所发送的名- 值对。

_<interface-name>Disp.java 

这个文件包含的是服务器端骨架类的定义,所用接口定义都要继承这个东西,这里的接口指供客户端调用的接口,如上图中的PrinterI.java

<interface-name>Holder.java 

    为接口定义holder 类,是对应Out参数使用的。一般参数都是值传递,这个类的作用是使参数通过引用传递。此类可以存放服务器返回给客户端的信息。

    客户端使用out 参数传递holder 类的实例,并在调用完成时检查每个out 参数的value 成员。下面的Slice定义,所有的参数都是作为out 参数传递的:

struct NumberAndString {
    int x;
    string str;
};

sequence<string> StringSeq;

dictionary<long, StringSeq> StringTable;

interface ServerToClient {
    void op1(out int i, out float f, out bool b, out string s);
    void op2(out NumberAndString ns,out StringSeq ss,
             out StringTable st);
    void op3(out ServerToClient* proxy);

};

    Slice 编译器为这个定义生成了以下out参数代码:

public interface ClientToServerPrx extends Ice.ObjectPrx {

    public void op1(Ice.IntHolder i,Ice.FloatHolder f, Ice.BooleanHolder b,Ice.StringHolder s);

    public void op2(NumberAndStringHolder ns, StringSeqHolder ss,StringTableHolder st);

    public void op3(ClientToServerPrxHolder proxy);

}

    假定我们有一个代理,指向的是ServerToClient 接口,客户代码可以这样传递参数:

ClientToServerPrx p = ...; // Get proxy...

Ice.IntHolder ih = new Ice.IntHolder();

Ice.FloatHolder fh = new Ice.FloatHolder();

Ice.BooleanHolder bh = new Ice.BooleanHolder();

Ice.StringHolder sh = new Ice.StringHolder();

p.op1(ih, fh, bh, sh);

NumberAndStringHolder nsh = new NumberAndString();

StringSeqHolder ssh = new StringSeqHolder();

StringTableHolder sth = new StringTableHolder();

p.op2(nsh, ssh, sth);

ServerToClientPrxHolder stcph = new ServerToClientPrxHolder();

p.op3(stcph);

System.out.writeln(ih.value);

    一旦操作调用完成,值就会出现在各个holder 实例中,你可以通过每个实例的value 成员访问这些值。

2. 客户端文件

<interface-name>Prx.java 

    这个是代理接口。例如PrinterPrx,在客户的地址空间中, PrinterPrx 的实例是“远地的服务器中的Printer接口的实例”的“本地大使”。与服务器端对象有关的所有细节,比如其地址、所用协议、对象标识,都封装在该实例中。
    这个类的方法调用都是远程服务端的调用,执行printString()方法的具体实现是在远程服务端执行的。

<interface-name>PrxHolder.java 

代理定义holder 类,用法参考<interface-name>Holder.java

<interface-name>PrxHelper.java 

这个是接口的代理定义助手类,客户端要得到服务端的servant的代理类,客户端不能通过new <interface-name>Prx()方式来获取代理对象,只能通过这个助手类,帮你获得代理对象。经常用的就两个方法checkedCast 和 uncheckedCast这两个方法实现的都是向下转换。
    注意, checkedCast 会联系服务器。这是必要的,因为只有服务器中的代理实现确切地知道某个对象的类型。所以checkedCast 可能会抛出ConnectTimeoutException 或ObjectNotExistException(这也解释了为何需要助手类:ICE在运行时必须联系服务器,所以我们不能使用Java 的向下转换)。
    与此相反, uncheckedCast 不会联系服务器,而是会无条件地返回具有所请求的类型的代理 。但是,如果你要使用uncheckedCast,你必须确定这个代理真的支持你想要转换到的类型;而如果你弄错了,你很可能会在调用代理上的操作时,引发运行时异常。对于这样的类型失配,最后可能会引发OperationNotExistException,但也有可能引发其他异常,比如整编异常。而且,如果对象碰巧有一个同名的操作,但参数类型不同,则有可能根本不产生异常,你最后就会把调用发送给类型错误的对象;这个对象可能会做出非常糟糕的事情。

_<interface-name>Del.java

_<interface-name>DelD.java

_<interface-name>DelM.java

    不用关心上面的这些文件,这些文件包含的是供Java 映射内部使用的代码;它们包含的功能与应用程序无关。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值