用RMI和CORBA举办漫衍式Java编程
当前位置:以往代写 > JAVA 教程 >用RMI和CORBA举办漫衍式Java编程
2019-06-14

用RMI和CORBA举办漫衍式Java编程

用RMI和CORBA举办漫衍式Java编程

副标题#e#

Java长途要领挪用(RMI)机制和公用工具请求署理体系(CORBA)是最重要 和利用最遍及的两种漫衍式工具系统。每个系统都有其特点和坏处。它们在行 业中被用于从电子生意业务到保健医疗的各个规模。一个项目假如要从这两种漫衍式 机制中选用一个,往往难以决议。本文归纳综合地先容了RMI和CORBA,更重要的是, 它将先容如何开拓一个有用的应用措施,用于从长途主机下载文件。

客户机/处事器模子是漫衍式计较的一种形式,在这种形式中,一个措施(客 户机)与另一个措施(处事器)通讯以便互换信息。在这种模子中,客户机和服 务器凡是都说同样的语言--也就是说客户机和处事器能领略同一个协议--这 样它们才气通讯。

固然客户机/处事器模子的实现方法多种多样,但典范做法是利用底层套接字。 利用套接字开拓客户机/处事器系统意味着,我们必需设计一个协议,也就是客户 机和处事器都认识的一组呼吁集,通过这些呼吁它们就能通讯了。举例来说, HTTP协议中提供了一个名为GET的要领,所有Web处事器都必需实现这个要领,所 有Web客户机(欣赏器)都必需利用这个要领,才气获取文档。

漫衍式工具模子

基于漫衍式工具的系统是一组工具的荟萃,这些工具以一种明晰界说封装的接 口把处事的请求者(客户机)和处事的提供者(处事器)脱离开。换言之,客户 机从处事的实现中疏散出来,酿成数据的泛起和可执行代码。这就是基于漫衍式 工具的模子与纯粹的客户机/处事器模子的主要区别之一。

在基于漫衍式工具的模子中,客户机向工具发送动静,然后工具表明该动静以 便抉择要执行什么处事。这项处事,也就是要领,可以选择是让工具照旧让署理 来执行。Java长途要领挪用(RMI)和公用工具请求署理体系(CORBA)就是这种 模子的例子。

RMI

RMI是一个漫衍式工具系统,它使你可以或许轻松地开拓出漫衍式Java应用措施。 在RMI中开拓漫衍式应用措施比用套接字开拓要简朴,因为不需要做设计协议这种 很容易堕落的事情。在RMI中,开拓者会有一种错觉,好像是从当地类文件挪用的 当处所法,其实参数传送给了长途方针,方针表明参数后再把功效发回给挪用方。

RMI应用措施劈头

利用RMI开拓漫衍式应用措施包罗以下步调:

界说一个长途接口

实现这个长途接口

开拓处事器

开拓客户机

生成存根和基干,启动RMI注册表、处事器和客户机

下面我们将通过开拓一个文件传输措施来实践这些步调。

典型:文件传输措施

这个应用措施答允客户机从长途主机上传送(即下载)任何范例的文件(纯 文本或二进制文件)。第一步是界说一个长途接口,这个接口划定了处事器所提 供要领的信号,客户机将挪用这些要领。

界说一个长途接口

用于文件下载应用措施的长途接口如代码典型1所示。接口 FileInterface提供了一个要领downloadFile,这个 要领接管String参数(文件名),将文件的数据以字节数组的形式 返回。

代码典型1 1: FileInterface.java

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
public byte[] downloadFile(String fileName) throws
RemoteException;
}

请留意FileInterface的以下特征:

它必需声明为public,这样客户机才气加载实现长途接口 的长途工具。

它必需扩展为Remote接口,以满意使该工具成为长途工具的 要求。

这个接口中的每种要领都必需投出一个java.rmi.RemoteException。


#p#副标题#e#

实现长途接口

下一步是实现接口FileInterface。实现的典型见代码典型2。 请留意,除了实现FileInterface之外,还把FileImpl 类扩展为UnicastRemoteObject。这暗示FileImpl类 将用于建设一个单独的、不行复制的长途工具,它利用RMI缺省的基于TCP的传送 通道举办通讯。

代码典型2: FileImpl.java

import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject
implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException{
super();
name = s;
}
public byte[] downloadFile(String fileName){
try {
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
} catch(Exception e){
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}
}
}

开拓处事器

第三个步调是开拓处事器。处事器需要做三件事:

建设RMISecurityManager的一个实例并安装它

建设长途工具(在本例中是FileImpl)的一个实例

在RMI注册表中挂号这个建设的工具。实现的典型见代码典型3。

代码典型 3: FileServer.java

#p#分页标题#e#

import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//127.0.0.1/FileServer", fi);
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}
}
}

语句Naming.rebind("//127.0.0.1/FileServer", fi)假定RMI 注册表在缺省的端标语1099上运行。可是,假如RMI注册表在其他端标语上运行, 就必需在这一句中指定端标语。譬喻,假如RMI注册表在端口4500上运行,那么 这一句就酿成:

Naming.rebind("//127.0.0.1:4500/FileServer", fi)

别的,在这里要着重指出,我们假定rmi注册表和处事器是在同一台电脑上运 行。假如不是这样,只需修改rebind要领中的地点即可。

#p#副标题#e#

开拓客户机

下一步是开拓客户机。客户机可以长途挪用长途接口 (FileInterface)中指定的任何要领。可是为了能这么做,客户 机首先必需从RMI注册表中得到指向该长途工具的引用。得到引用之后就可以调 用downloadFile要领了。客户机的实现请见代码典型4。在这个实 现中,客户机从呼吁行吸收两个参数:

第一个参数是要下载文件的名称,第二个参数是要下载的文件地址主机的地 址,也就是运行文件处事器的那台电脑的地点。

代码典型4: FileClient.java

import java.io.*;
import java.rmi.*;
public class FileClient{
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
try {
String name = "//" + argv[1] + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
byte[] filedata = fi.downloadFile(argv[0]);
File file = new File(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}
}
}

运行应用措施

为了运行应用措施,我们需要生成存根和基干,编译处事器和客户机,启动 RMI注册表,最后是启动处事器和客户机。

为了生成存根和基干,请利用rmic编译器:

prompt> rmic FileImpl

这将生成两个文件:FileImpl_Stub.class和 FileImpl_Skel.class。存根是一个客户机署理,基干是一个服 务器基干。

下一步是编译处事器和客户机。用javac编译器来做这件事。可是请留意:如 果处事器和客户机是在两台差异的呆板上开拓的,为了编译客户机,需要把接口 (FileInterface)复制一份。 最后,启动RMI注册表并运行处事器和客户机。为了在缺省的端标语上启动 RMI注册表,请在Windows中利用呼吁rmiregistry或 start rmiregistry。为了在其他端标语上启动RMI注册表,可以 提供该端标语作为RMI注册表的一个参数:

prompt> rmiregistry portNumber

运行RMI注册表之后,就可以启动处事器FileServer了。可是, 因为在处事器应用措施中正在利用RMI安详打点员,所以需要一个安详目的来与之 相配。下面是一个安详目的典型:

grant {
permission java.security.AllPermission "", "";
};

留意: 这只是一个目的的例子。它答允任何人做任何工作。对付要害 性事务应用措施,你需要指定更严格的安详目的。

此刻,为了启动处事器,需要把除了客户机类 (FileClient.class)之外的所有类(包罗存根和基干)复制一 份。请利用以下呼吁启动处事器,假定安详目的位于文件policy.txt中:

prompt> java -Djava.security.policy=policy.txt FileServer

为了在另一台呆板上启动客户机,需要复制长途接口 (FileInterface.class)和存根 (FileImpl_Stub.class)。请利用以下呼吁启动客户机:

prompt> java FileClient fileName machineName

#p#分页标题#e#

个中fileNamefileName是要下载的文件,machineName 是该文件地址的呆板(运行文件处事器的那台呆板)。假如一切顺利,那么客户 机就存在了,下载完的文件生存在当地的呆板上。

要运行前面先容的客户机,需要复制接口和存根。更 适当的要领是利用RMI动态类加载。这种做法不需要复制接口和存根。取而代 之的做法是,可以把接口和存根放在共享的目次里供处事器和客户机利用,在 需要存根可能基干的时候,RMI类加载器就会自动下载它。举例来说,用以下命 令运行客户机:java -Djava.rmi.server.codebase=http://hostname/locationOfClasses FileClient fileName machineName。

    关键字:

在线提交作业