学习笔记:JAVA RMI远程方法调用简单实例

news/2024/12/23 12:42:51 标签: java, 开发工具, 网络

RMI的概念

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

  RMI的开发步骤

  先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote

  开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject

  通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象

  最后客户端查找远程对象,并调用远程方法

  简单实例

  首先为服务建立一个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类
public interface 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
public class PersonServiceImpl extends UnicastRemoteObject implements PersonService {
public PersonServiceImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
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.*;
public class Program{
public static void 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.*;
public class Program {
public static void 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();
}
}
}

  常见错误

  在命令提示符调用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

  在调用javac命令时出现“javac 找不到文件 ..... ”此错误,可能是因为阁下输入的文件路径出现错误造成,注意不要把D:\\RMI\RemotingService\src>javac rmi/remotingservice/Program.java写错为D:\\RMI\RemotingService\src>javac rmi.remotingservice.Program.java

  在调用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"。   



最新内容请见作者的GitHub页:http://qaseven.github.io/

   


http://www.niftyadmin.cn/n/712305.html

相关文章

一步一步学习Redis——简介与安装

1.Redis REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统&#xff0c;是跨平台的非关系型数据库。 Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库…

廉洁修身论文2000字_论文3000字符是几个版面

点击上方蓝字 关注我们1论文发表中字数要求是一项最基本要求&#xff0c;字数的多少关系到文章见刊占用的版面&#xff0c;很多作者在发表前也会对自己的文章以及所占版面进行大致的估算&#xff0c;控制字数对于作者和期刊来说都是很有必要的&#xff0c;论文3000字符是几个版…

jforum mysql_在linux環境下搭建JDK+JAVA+Mysql,並完成jforum的安裝

參考鏈接&#xff1a;YUM安裝MySQL和JDK和Tomcat&#xff1a;http://cmdschool.blog.51cto.com/2420395/1696206/因為我使用的是普通用戶lily&#xff0c;如果使用root的話&#xff0c;所有命令不用加sudo即可。今天先不加圖&#xff0c;改天再試試可以的話&#xff0c;再補充。…

希捷正式发布12TB硬盘:二代充氦 单碟1.5TB

在透露已经出样之后&#xff0c;希捷今天正式发布了新款Enterprise Capacity v7 12TB硬盘&#xff0c;这也是希捷的第二代充氦技术硬盘&#xff0c;面向企业和云计算市场。相比于此前的Enterprise Capacity v6 10TB&#xff0c;新硬盘增强了充氦技术&#xff0c;单盘封装多达八…

NTF服务器搭建及其遇到问题

1&#xff0c;服务器端软件&#xff1a;安装nfs-utils和rpcbindnfs-utils&#xff1a; 提供rpc.nfsd 及 rpc.mountd这两个NFS DAEMONS的套件 rpcbind: NFS其实可以被看作是一个RPC SERVER PROGRAM,而要启动一个RPC SERVER PROGRAM&#xff0c;都要做好客户端IP及其PORT的对应工…

web前端学习(二十三)——CSS3定位(position)、元素裁剪(clip)及鼠标样式(cursor)属性的相关设置

1.CSS定位属性&#xff08;position&#xff09; position 属性指定了元素的定位类型。 position 属性的五个值&#xff1a; staticrelativefixedabsolutesticky元素可以使用的顶部&#xff0c;底部&#xff0c;左侧和右侧属性定位。然而&#xff0c;这些属性无法工作&#xff…

python自定义结束符号_Python输入恐怖-未定义的符号-用于自定义C++ MODU

我在Ubuntu 11.04上使用OpenCV 2.3到2.4.2开发了一个C的Python模块。OpenCV是从源代码构建的。我没有使用Ubuntu存储库中的OpenCV版本。我的Python模块编译没有问题&#xff0c;并且在Python中正确加载。然而&#xff0c;当我在Ubuntu11.10或12.04上编译这个模块时&#xff0c;…

QT多线程之---moveToThread用法

在gui编程里&#xff0c;一个子函数的运行时间可能过长&#xff0c;界面就处于假死状态&#xff0c;原因是窗口是一个线程&#xff0c;子函数也在这个线程里&#xff0c;一些事件也要在这个线程里处理。 如果子函数运行时间过长&#xff0c;系统没有办法调用事件监听循环&#…