来源:http://www.cnblogs.com/leslies2/archive/2011/05/20/2051844.html

RMI的概念

RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。使用这种机制,某一台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据。RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote Procedure Call)应运而生,它使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持,而且RPC未能做到面向对象调用的开发模式。针对RPC服务遗留的问题,RMI出现在世人面前,它被设计成一种面向对象的通讯方式,允许程序员使用远程对象来实现通信,并且支持多线程的服务,这是一次远程通讯的革命,为远程通信开辟新的里程碑。

RMI的开发步骤

  1. 先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote
  2. 开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject
  3. 通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象
  4. 最后客户端查找远程对象,并调用远程方法

简单实例

首先为服务建立一个Model层,注意因为此对象需要现实进行远程传输,所以必须继承Serializable

package rmi.model;

import java.io.Serializable;

//注意对象必须继承Serializable
publicclass PersonEntity implements Serializable {
privateint id;
private String name;
privateint age; publicvoid setId(int id) {
this.id = id;
} publicint getId() {
return id;
} publicvoid setName(String name) {
this.name = name;
} public String getName() {
return name;
} publicvoid setAge(int age) {
this.age = age;
} publicint getAge() {
return age;
}
}

创建远程接口PersonService,注意远程接口需要继承Remote

package rmi.service;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
import rmi.model.*; //此为远程对象调用的接口,必须继承Remote类
publicinterface PersonService extends Remote {
public List<PersonEntity> GetList() throws RemoteException;
}

建立PersonServiceImpl实现远程接口,注意此为远程对象实现类,需要继承UnicastRemoteObject

package rmi.serviceImpl;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.LinkedList;
import java.util.List; import rmi.model.PersonEntity;
import rmi.service.*; //此为远程对象的实现类,须继承UnicastRemoteObject
publicclass PersonServiceImpl extends UnicastRemoteObject implements PersonService { public PersonServiceImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
} @Override
public List<PersonEntity> GetList() throws RemoteException {
// TODO Auto-generated method stub
System.out.println("Get Person Start!");
List<PersonEntity> personList=new LinkedList<PersonEntity>(); PersonEntity person1=new PersonEntity();
person1.setAge(25);
person1.setId(0);
person1.setName("Leslie");
personList.add(person1); PersonEntity person2=new PersonEntity();
person2.setAge(25);
person2.setId(1);
person2.setName("Rose");
personList.add(person2); return personList;

}

建立服务器端,在服务器端注册RMI通讯端口与通讯路径,然后通讯javac命令编译文件,通过java -server 命令注册服务。以下面代码为例,如果阁下将项目建立于D:\\RMI\RemotingService文件夹上时,则先输入D:\\RMI\RemotingService\src>javac rmi/remotingservice/Program.java获取Program.class(如何阁下使用的MyEclipse等开发工具,可跳过此步,直接在*/bin文件夹中直接调用已经生成的Program.class),然后输入D:\\RMI\RemotingService\src>java rmi/remotingservice/Program启动服务。

package rmi.remotingservice;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry; import rmi.service.*;
import rmi.serviceImpl.*; publicclass Program{ publicstaticvoid main(String[] args) {
try {
PersonService personService=new PersonServiceImpl();
//注册通讯端口
LocateRegistry.createRegistry(6600);
//注册通讯路径
Naming.rebind("rmi://127.0.0.1:6600/PersonService", personService);
System.out.println("Service Start!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

最后建立客户端进行测试,注意客户调用的RMI路径必须服务器配置一致

package rmi.remotingclient;

import java.rmi.Naming;
import java.util.List; import rmi.model.PersonEntity;
import rmi.service.*; publicclass Program {
publicstaticvoid main(String[] args){
try{
//调用远程对象,注意RMI路径与接口必须与服务器配置一致
PersonService personService=(PersonService)Naming.lookup("rmi://127.0.0.1:6600/PersonService");
List<PersonEntity> personList=personService.GetList();
for(PersonEntity person:personList){
System.out.println("ID:"+person.getId()+" Age:"+person.getAge()+" Name:"+person.getName());
}
}catch(Exception ex){
ex.printStackTrace();
}
}
}

常见错误

    1. 在命令提示符调用java命令时,显示并无此命令。这是因为未在“环境变量”中绑定JAVA的JDK命令造成的,你首先单击“计算机右键”->“属性”->“高级”->“环境变量”。在系统变量Path设置中加载为JDK的路径  .;D:\Program Files\Genuitec\Common\binary\com.sun.java.jdk.win32.x86_1.6.0.013\bin。然后在ClassPath加载服务器端的Program.class地址 .;D:\\RMI\RemotingService\bin
    2. 在调用javac命令时出现“javac 找不到文件 ..... ”此错误,可能是因为阁下输入的文件路径出现错误造成,注意不要把D:\\RMI\RemotingService\src>javac rmi/remotingservice/Program.java写错为D:\\RMI\RemotingService\src>javac rmi.remotingservice.Program.java
    3. 在调用D:\\RMI\RemotingService\bin>java rmi/remotingservice/Program命令时出现“Exception in thread 'main' java.lang.NoClassEdfoundError”错误,第一这可能是阁下把Program错写为Program.class,注意java命令不需要加后缀名。第二可能是阁下把“java rmi/remotingservice/Program”错写为“java rmi\remotingservice\Program"。

JAVA RMI远程方法调用简单实例(转载)的更多相关文章

  1. JAVA RMI远程方法调用简单实例[转]

    RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外 一台 ...

  2. Java RMI 实现一个简单的GFS(谷歌文件系统)——介绍篇

    本系列主要是使用Java RMI实现一个简单的GFS(谷歌文件系统,google file system),首先整体简单介绍下该项目. [为了更好的阅读以及查看其他篇章,请查看原文:https://w ...

  3. Java RMI 实现一个简单的GFS(谷歌文件系统)——背景与设计篇

    目录 背景 系统设计 1. 系统功能 2. Master组件 2.1 命名空间 2.2 心跳机制 2.3 故障恢复和容错机制 3. ChunkServer组件 3.1 本地存储 3.2 内存命中机制 ...

  4. Java RMI(远程方法调用) 实例与分析 (转)

    目的: 通过本文,可以加深对Java RMI的理解,知道它的工作原理,怎么使用等. 也为了加深我自己的理解,故整理成文.不足之处,还望指出. 概念解释: RMI(RemoteMethodInvocat ...

  5. Java RMI(远程方法调用) 实例与分析

    目的: 通过本文,可以加深对Java RMI的理解,知道它的工作原理,怎么使用等. 也为了加深我自己的理解,故整理成文.不足之处,还望指出. 概念解释: RMI(RemoteMethodInvocat ...

  6. java rmi远程方法调用实例

    RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外一台计 ...

  7. MySQL 触发器简单实例 - 转载

    MySQL 触发器简单实例 触发器:可以更新,删除,插入触发器,不同种类的触发器可以存在于同一个表,但同种类的不能有多个.一个更新.一个删除是可以共存的. ~~语法~~ CREATE TRIGGER  ...

  8. Java WebService 简单实例[转载]

    [注意,本文转载自  http://hyan.iteye.com/    ] 一.准备工作(以下为本实例使用工具) 1.MyEclipse10.7.1 2.JDK 1.6.0_22 二.创建服务端 1 ...

  9. redis在Java web项目的简单应用(转载)

    看到一篇关于redis和spring集成的文章,实际测试后,可以.转载以备用.谢谢 亲昵YY! html,body { font-size: 15px } body { font-family: He ...

随机推荐

  1. poj1734Sightseeing trip

    Sightseeing trip Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6811   Accepted: 2602 ...

  2. Python Base Five

    // 8 day(2016/8/11) 38. In python , it is oop. class Baskball:         def setName(self, name):      ...

  3. python 粘包问题及解决方法

    一粘包 TCP协议是面向对象的,面向流的,提高可靠性服务.使用了优化算法,Nagle算法.将多次间隔较少且数据量小的数据,合并成一个大的数据块,然后进行封包.这样接收端就很难分辨出来.TCP协议数据是 ...

  4. Django标签之包含标签Inclusion tags

    Django过滤器和标签功能很强大,而且支持自定义标签,很是方便:其中一种标签是Inclusion tags,即包含标签,个人感觉比较反人类的 包含标签(Inclusion tags)通过渲染其他的模 ...

  5. 洛谷 P 1514 引水入城==Codevs 1066

    题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. ...

  6. 【CF1017B】The Bits(模拟)

    题意:给定两个二进制数字a,b,可以任意交换a中的两个bit位,求进行这样一次操作,最多可产生多少种不同的a or b n<=1e5 思路:模拟,分类讨论 #include<cstdio& ...

  7. 【CF725D】Contest Balloons(贪心,堆)

    题意:acm队伍可以得气球,相同气球数是一个排名.每个队伍有一个气球数上限,如果该队伍的气球数大于上限 该队伍被淘汰.给了你队伍的气球数,你的气球可以给别人,问你最大可能的排名. (2 ≤ n ≤ 3 ...

  8. 2017 UESTC Training for Data Structures-解题报告

    题目链接:http://acm.uestc.edu.cn/#/contest/show/155 这个数据结构训练主要针对线段树,树转数组和并查集.比较适合刚入门数据结构的同学. 注意,因为后面题的代码 ...

  9. 为什么linux下多线程程序如此消耗虚拟内存【转】

    转自:http://blog.csdn.net/chen19870707/article/details/43202679 权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 探 ...

  10. Java通过开启线程池实现多线程

    计算1..100  和1...200 的和,使用线程池开启两个线程 调用Executors类的newFixedThreadPool方法参数是线程池容纳的线程数量 这里是2 返回的对象是 Executo ...