使用JavaCard RMI接口 |
| 电脑学习网,xuef.com,最全最新最权威的电脑知识网站. |
Java Card小应用程序编程的第二个模型是JavaCard RMI ( JCRMI),严格的说它是J2SE RMI分布对象模型的缩小版。
这是一个以对象为中心的模型,根据这个模型你在上一节看到的APDU通信和句柄将被抽象化;取而代之的是你处理对象。这简化了编程和集成基于Java Card技术的设备。
在RMI模型中,一个服务器应用程序创建并生成可访问的远程对象,并且一个客户应用程序获得到服务器的远程对象的远程引用,然后调用它们的远程方法。在JCRMI中,Java Card小应用程序是服务器,而主应用程序是客户端。 JavaCard RMI简介
两个程序包提供了JavaCard RMI支持:
1、java.rmi定义了Java 2标准版java.rmi程序包的一个子集。它定义了Remote接口和RemoteException类。除此之外,没有包含其他传统的java.rmi类。 2、Javacard.framework.service定义了Java Card小应用程序服务类,包括RMI服务类CardRemoteObject和RMIService。
3、Class CardRemoteObject定义了两个方法启动和禁止卡片外的对象的远程访问。类RMIService处理RMI请求(转化输入的命令APDU为远程方法调用)。
编写一个JCRMI应用程序类似于编写一个典型的基于RMI的应用程序:
1.定义远程类的行为为一个接口。
2.编写远程类的服务器实现,和支持类。
3.编写一个使用远程服务的客户机程序和支持类。
注意JCRMI没有改变小应用程序的基本结构或者生命周期,你不久就会看到。
远程接口
创建一个远程服务中的第一步是定义它的可见行为。远程接口定义你的小应用程序提供的服务。和在标准的J2SE RMI中一样,所有的Java Card RMI远程接口必须扩展java.rmi.Remote接口。为了说明,这里有一个远程接口,揭示一个取得保存在卡片里的余额的方法:
import java.rmi.*; import javacard.framework.*;
public interface MyRemoteInterface extends Remote { ... public short getBalance() throws RemoteException; ... // A complete credit card application would also define other // methods such as credit() and debit() methods. ... }
列表1、远程接口
MyRemoteInterface定义这个远程方法,在我们的示例中一个getBalance ()方法,来取得保存在智能卡中的余额。注意,除了Java Card特定的导入之外,这个远程接口看起来完全象一个标准的RMI远程接口。 服务器实现
下一步是实现服务器的行为。服务器实现包含Java Card小应用程序,在所有的你已经定义的远程接口当中的实现,和任何与你的应用程序相关的特定类。
Java Card小应用程序
Java Card小应用程序是JCRMI服务器,并且是主机(客户端)应用程序可用的远程对象的所有者。一个典型的Java Card RMI小应用程序的结构在下面的图表中说明:
 Figure 4. 典型的JavaCard RMI应用程序结构
当和明确地处理APDU消息的小应用程序相比,基于JCRMI的小应用程序更像一个对象容器。如图4所示,基于JCRMI的小应用程序有一个或多个远程对象,一个APDU Dispatcher和一个接收APDU并且把它们转化为远程方法调用的RMIService。Java Card远程类可以扩展CardRemoteObject类,自动导出对象,使之可用于远程使用。
JCRMI小应用程序必须扩展javacard.framework.Applet,遵循标准的小应用程序结构,并且定义适当的生命周期方法。它必须安装并且登记本身,并且分配APDU。下面这一代码片断说明一个基于JCRMI的小应用程序的典型结构:
public class MyApplet extends javacard.framework.Applet {
private Dispatcher disp; private RemoteService serv; private Remote myRemoteInterface;
/** * Construct the applet. Here instantiate the remote * implementation(s), the APDU Dispatcher, and the * RMIService. Before returning, register the applet. */ public MyApplet () { // Create the implementation for my applet. myRemoteInterface = new MyRemoteInterfaceImpl(); // Create a new Dispatcher that can hold a maximum of 1 // service, the RMIService. disp = new Dispatcher((short)1); // Create the RMIService serv = new RMIService(myRemoteInterface); disp.addService(serv, Dispatcher.PROCESS_COMMAND); // Complete the registration process register(); } ... 小应用程序创建一个Dispatcher和一个处理输入的JCRMI APDU的RMIService。
... /** * Installs the Applet. Creates an instance of MyApplet. * The JCRE calls this static method during applet * installation. * @param bArray install parameter array. * @param bOffset where install data begins. * @param bLength install parameter data length. */ public static void install(byte[] aid, short s, byte b) { new MyApplet(); } 在JavaCard环境中,JVM的生命周期是物理卡片的生命周期,而不是提供垃圾收集器的所有的Java Card实现的,所以你需要最小化内存分配。在安装时间创建对象,这样内存只被分配给它们一次。
/** * Called by the JCRE to process an incoming APDU command. An * applet is expected to perform the action requested and * return response data, if any. * * This JCRMI version of the applet dispatches remote * invocation APDUs by invoking the Dispatcher. * * Upon normal return from this method the JCRE sends the ISO- * 7816-4-defined success status (90 00) in the APDU response. * If this method throws an ISOException, the JCRE sends the * associated reason code as the response status instead. * @param apdu is the incoming APDU. * @throw ISOException if the install method fails. */ public void process(APDU apdu) throws ISOException { // Dispatch the incoming command APDU to the RMIService. disp.process(apdu); } 代码列表13.Java Card RMI小应用程序
小应用程序的process()方法接收一个APDU命令并且把它发送到RMIService,RMIService通过把它转化为一个RMI调用和后续响应处理这条命令。
实现远程对象
实现一个JCRMI远程对象类似于实现标准的J2SE RMI远程对象。主要区别是在JCRMI中你的远程对象有扩展CardRemoteObject的选择(除了实现你的远程接口之外)。
CardRemoteObject定义两个方法export()和unexport(),分别允许或者禁止从卡外到对象的访问。通过扩展CardRemoteObject,你自动地导出你的远程对象所有的方法。如果你决定不扩展CardRemoteObject,你将要负责通过调用CardRemoteObject.export()导出它们。
import java.rmi.RemoteException; import javacard.framework.service.CardRemoteObject; import javacard.framework.Util; import javacard.framework.UserException; /** * Provides the implementation for MyRemoteInterface. */ public class MyRemoteImpl extends CardRemoteObject implements MyRemoteInterface { /** The balance. */ private short balance = 0;
/** * The Constructor invokes the superclass constructor, * which exports this remote implementation. */ public MyRemoteImpl() { super(); // make this remote object visible }
/** * This method returns the balance. * @return the stored balance. * @throws RemoteException if a JCRMI exception is * encountered */ public short getBalance() throws RemoteException { return balance; }
// Other methods ... } 列表⒕远程对象实现
一个完整的Java Card RMI应用程序的流程
让我们概述一个JCRMI应用程序的流程。客户端(主机)应用程序通过传递RMI APDU到卡上的JCRE来产生RMI调用,依次转送这些APDU到相应的JCRMI小应用程序。这个小应用程序分配接收的APDU到RMIService,依次处理APDU并且转化它为一个RMI调用。一个JCRMI小应用程序的典型流程在下面说明:
 Figure 5. 基于JavaCard RMI模型的应用程序流程
简言之,JCRMI提供一个基于APDU的消息传递模型的分布式对象模型机制。JCRMI消息被封装到传送到RMIService的APDU消息中,负责解码APDU命令,并且转化这些命名到方法调用和响应。这允许服务器和客户端通信,来回传送方法信息、参数和返回值。
|
|
|
|
|
|
|