RMI(Remote Method Invocation 远程方法调用),它增强了JAVA开发分布式应用的能力。
运行机制;
RMI应用程序通常包括两个独立的程序:服务器程序和客户端程序。典型的服务器应用程序将创建多个远程对象,使这些远程对象能够被引用,然后等待客户端调用这些远程对象的方法,而典型的客户端程序则从服务器中得到一个或多个远程对象的引用,然后调用远程对象的方法。RMI为服务器和客户端进行通信和信息传递提供了一种机制。
在RMI分布式应用系统中,服务器与客户机之间传递的JAVA对象必须是可序列化的对象。不可序列化的对象不能在对象流中进行传递。对象序列化扩展了核心JAVA输入/输出类,同时也支持对象。对象序列化支持把对象编码以及将通过它们可访问到的对象编码变成字节流;同时,它也支持流中对象图形的互补重构造。
开发步骤:
在这里推荐一款PLUG-IN FOR ECLIPSE,http://www.genady.net/rmi/v20/,可以提供自动生成STUB和发布RMI,生成security.policy的作用。其站定也提供了一个DEMO,比较简单。
服务端:首先定义REMOTE接口
所有的远程方法都需要启动REMOTEEXCEPTION方法,执行异常检查。远程对象必须实现此接口
如果你使用的IDE实现,将自动编译,并利用上文中提到了RMI的PLUGIN来完成STUB的生成。如果是利用JDK的相关命令,比较繁琐,在此不介绍。
运行服务端程序
利用此CREATE方法就不需要在CMD中启动RMI的端口设置了。
关于客户端程序:
注意,在真实场景发布时需要将远程接口打包成JAR发布到客户端;否则将造成客户端无法找到需要的远程接口。
运行机制;
RMI应用程序通常包括两个独立的程序:服务器程序和客户端程序。典型的服务器应用程序将创建多个远程对象,使这些远程对象能够被引用,然后等待客户端调用这些远程对象的方法,而典型的客户端程序则从服务器中得到一个或多个远程对象的引用,然后调用远程对象的方法。RMI为服务器和客户端进行通信和信息传递提供了一种机制。
在RMI分布式应用系统中,服务器与客户机之间传递的JAVA对象必须是可序列化的对象。不可序列化的对象不能在对象流中进行传递。对象序列化扩展了核心JAVA输入/输出类,同时也支持对象。对象序列化支持把对象编码以及将通过它们可访问到的对象编码变成字节流;同时,它也支持流中对象图形的互补重构造。
开发步骤:
在这里推荐一款PLUG-IN FOR ECLIPSE,http://www.genady.net/rmi/v20/,可以提供自动生成STUB和发布RMI,生成security.policy的作用。其站定也提供了一个DEMO,比较简单。
服务端:首先定义REMOTE接口
public interface RemotePrinter extends Remote {
public int sumbitJob(String text) throws RemoteException;
/**
*
* @param jobID the job id returned from {@link #sumbitJob(String)}
* @return
* @throws RemoteException
*/
public boolean isComplete(int jobID) throws RemoteException;
public String getPrinterStatus() throws RemoteException;
}
所有的远程方法都需要启动REMOTEEXCEPTION方法,执行异常检查。远程对象必须实现此接口
public class RemotePrinterImpl extends UnicastRemoteObject implements
RemotePrinter {
protected RemotePrinterImpl() throws RemoteException {
}
/**
*
*/
private static final long serialVersionUID = -693485476235003575L;
public String getPrinterStatus() throws RemoteException {
return "ddddd";
}
public boolean isComplete(int jobID) throws RemoteException {
System.out.println("requested printer status");
return true;
}
public int sumbitJob(String text) throws RemoteException {
System.out.println("submitted job"+text);
return 0;
}
}
该具体实现集成了UnicastRemoteObject和实现创建的远程对象的类;
如果你使用的IDE实现,将自动编译,并利用上文中提到了RMI的PLUGIN来完成STUB的生成。如果是利用JDK的相关命令,比较繁琐,在此不介绍。
运行服务端程序
public static void main(String[] args)
{
try {
System.setProperty("java.rmi.server.hostname","192.168.2.176"); //设置服务器IP
Registry r = LocateRegistry.createRegistry(2000);//创建RMI的启动端口,默认并非此端口。
r.rebind("printer", new RemotePrinterImpl());//绑定对象
System.out.println("printer starting!");
} catch (Exception e) {
e.printStackTrace();
}
}
利用此CREATE方法就不需要在CMD中启动RMI的端口设置了。
关于客户端程序:
public class PrintClient {
public static void main(String[] args)
{
try {
System.setSecurityManager(new RMISecurityManager());//加入此方法必须存在security.policy文件
RemotePrinter printer = (RemotePrinter) Naming.lookup("rmi://192.168.2.176:2000/printer");
int jobID = printer.sumbitJob("hello world");
System.out.println("submitted job "+jobID);
System.out.println("Is job complete?"+printer.isComplete(jobID));
System.out.println("printer status?"+printer.getPrinterStatus());
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意,在真实场景发布时需要将远程接口打包成JAR发布到客户端;否则将造成客户端无法找到需要的远程接口。