一个相当经典的RMI实例源代码及详细说明
RMI技术
下面以一个例子说明怎么使用RMI技术。这个例子演示了怎样将一个文件上传到服务器和怎样将一个文件从服务器上下载下来。
使用RMI技术共有6个步骤要走: (1)定义和实现远端接口中的参数 (2) 定义和实现远端接口 (3) 编写服务端代码 (4)编写客户端代码 (5)生成stub和skeltion ,并将stub打包到客户端jar中,将skeltion打包到服务端jar中 (6)启动rmiregistry , 并将服务注册到rmiregistry中,然后运行代码。下面就这六个方面说明rmi技术。
定义和实现远端接口中的参数
(1)定义远端接口中的参数
每一个远端接口中的参数都必须是可序列化的。那么,如何定义一个序列化的接口呢,简单,只需从java.io.Serializable继承即可,如下所示:
import java.io.Serializable;
public interface FileInformation extends Serializable {
String getName();
byte[] getContent();
void setInformation(String name , byte[] content);
};
(2)实现远端接口中的参数。
实现远端接口中的参数的接口跟与实现其他任何接口没什么不一样的地方,如下所示
public class FileInformationSev implements FileInformation {
private String name = null ;
private byte[] content = null ;
public String getName() {
return name ;
}
public byte[] getContent() {
return content;
}
public void setInformation(String name, byte[] content) {
this.name = name ;
this.content = content ;
}
}
那么,为什么要序列化远端接口中的参数(返回值) ?这是因为需要将客户端的对象(参数)转化成byte stream,通过网络协议传输到服务端,再还原成服务端的对象进行调用。或者是需要将服务端的对象(返回值)转化成byte stream,通过网络协议传输到服务端,再还原成客户端的对象进行调用。
在 jdk中, java.lang包和java.util包下的类都已经实现了序列化,直接可以用在远程接口中作参数或返回值;所有的基本类型也可以直接用在远程接口中作参数或返回值;
定义和实现远端接口
(1)定义远端接口
远端接口必须从java.rmi.Remote继承;远端接口中的方法如果要throw异常,这个异常必须是java.rmi.RemoteException(或java.rmi.RemoteException的子类),否则,这个异常就不能被返回到客户端。Example如下:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface LoadFile extends Remote {
void upLoadFile(FileInformation fileInof) throws RemoteException;
FileInformation downLoadFile(String filename) throws RemoteException ;
}
(2)实现远端接口
实现远端接口比较容易,跟其他接口的实现没有什么区别,如下所示:
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.io.IOException;
import java.io.File;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.rmi.server.UnicastRemoteObject;
public class LoadFileService extends UnicastRemoteObject implements LoadFile {
private String currentDir= null ;
// this contruction is needed
public LoadFileService() throws RemoteException {
super();
}
public void setCurrentDir(String currentDir){
this.currentDir = currentDir ;
}
public void upLoadFile(FileInformation fileInfo) throws RemoteException{
BufferedOutputStream output = null ;
try{
// check paramter
if(fileInfo == null ){
throw new RemoteException("the paramter is null ");
}
//check fileName and content
String fileName = fileInfo.getName() ;
byte [] content = fileInfo.getContent() ;
if(fileName == null || content == null ){
throw new RemoteException("the file or the content is null ");
}
//create file
String filePath = this.currentDir + "\\" + fileName ;
File file = new File(filePath);
if(!file.exists()){
file.createNewFile();
}
//save the content to the file
output = new BufferedOutputStream(new FileOutputStream(file));
output.write(content);
}catch(RemoteException ex){
throw ex ;
}catch(Exception ex){
throw new RemoteException(ex.getLocalizedMessage());
}finally{
if(output != null ){
try{
output.close();
output = null ;
}catch(Exception ex){
}
}
}
}
public FileInformation downLoadFile(String fileName) throws RemoteException {
FileInformation fileInfo = null ;
BufferedInputStream input = null ;
try{
// check paramter
if(fileName == null){
throw new RemoteException("the paramter is null ");
}
// get path
String filePath = this.currentDir + "\\" + fileName ;
File file = new File(filePath);
if(!file.exists()){
throw new RemoteException("the file whose name is " + fileName + " not existed ");
}
// get content
byte[] content = new byte[(int)file.length()];
input = new BufferedInputStream(new FileInputStream(file));
input.read(content);
// set file name and content to fileInfo
fileInfo = new FileInformationSev();
fileInfo.setInformation(fileName , content);
}catch(RemoteException ex){
throw ex ;
}catch(Exception ex){
throw new RemoteException(ex.getLocalizedMessage());
}finally{
if(input != null ){
try{
input.close();
input = null ;
}catch(Exception ex){
}
}
}
return fileInfo ;
}
}
编写服务端代码
服务端代码主要有3个步骤:
(1)加载安全管理器
(2)创建一个服务对象
(3)将这个服务对象注册到命名服务上
:
import java.rmi.RMISecurityManager;
import java.rmi.Naming;
public class RMIServer {
public static void main(String[] args) {
try{
//加载安全管理器
System.setSecurityManager(new RMISecurityManager() );
//创建一个服务对象
LoadFileService server = new LoadFileService();
server.setCurrentDir("c:\\rmiexample");
//将服务对象注册到rmi注册服务器上,而不是其他服务器
//(因为LoadFileService extends UnicastRemoteObject)
Naming.rebind("//127.0.0.1:2000/LoadFileServer", server);
}catch(Exception ex){
System.out.println(ex.getLocalizedMessage());
ex.printStackTrace();
}
}
}
注意:将对象注册以后,不可关闭服务对象。
编写客户端代码
客户端代码需要两个步骤:
(1)根据服务的名称,查找服务对象
(2)调用服务服务对象对应的方法完成工作
在这个例子中,我们从客户端上传一个文件到服务器,并将服务器的一个文件下载下来。
代码如下:
import java.io.IOExcep
相关推荐
源码说明: VB精彩编程100个源代码实例,实例很丰富,涉及的内容方方面面。有音量控制、拾色器、画图、抓屏、文本操作、获取操作系统信息、拖拉节点、查看文件属性、渐变窗体、计算器等。这些都是能独立运行的小程序...
微信商城小程序 完整实例源代码微信商城小程序 完整实例源代码微信商城小程序 完整实例源代码微信商城小程序 完整实例源代码微信商城小程序 完整实例源代码微信商城小程序 完整实例源代码微信商城小程序 完整实例源...
QT5开发及实例配套[源代码] Qt是诺基亚公司的C++可视化开发平台,本书以Qt 5作为平台,每个章节在简单介绍开发环境的基础上,用一个小实例,介绍Qt 5应用程序开发各个方面,然后系统介绍Qt 5应用程序的开发技术,...
html5 简单实例源代码
100个Java经典编程实例源代码,不需要解压密码,绝对可用
这个"asp.net实例源代码合集"显然是一个包含多种ASP.NET应用场景的代码库,可能涵盖从基础到高级的各种技术。 在ASP.NET中,你可以了解到以下关键知识点: 1. **页面生命周期**:ASP.NET页面经历一系列的生命周期...
【推荐】100个Java经典编程实例源代码是一份非常适合Java初学者深入学习和实践的资源集合。这个压缩包包含了一系列精心挑选的Java编程示例,覆盖了各种基础到进阶的编程概念,旨在帮助学习者巩固Java编程技能。 在...
Visual c++实例精通的实例源代码 便于初学者学习使用。便于c++ 的提高
"java经典实例源代码"这个资源包含了一百个不同的编程实例,可以帮助开发者深入理解Java语言的工作原理,并提供实际操作的经验。 1. **面向对象编程**:Java是一种面向对象的语言,实例中的代码会展示如何定义类、...
VB精彩编程100个源代码实例,实例很丰富,涉及的内容方方面面。有音量控制、拾色器、画图、抓屏、文本操作、获取操作系统信息、拖拉节点、查看文件属性、渐变窗体、计算器等。这些都是能独立运行的小程序,每一个都...
这个“基于RMI分布计算实例java源代码”提供了一个具体的例子,展示了如何利用RMI进行分布式计算,特别是实现了两个矩阵的相乘操作。在本文中,我们将深入探讨RMI的工作原理以及如何在实际应用中实施矩阵乘法。 ...
JSP动态网站设计实例教程源代码免费下载JSP动态网站设计实例教程源代码免费下载JSP动态网站设计实例教程源代码免费下载JSP动态网站设计实例教程源代码免费下载 JSP动态网站设计实例教程源代码免费下载
VC++游戏开发特殊技巧实例源代码锦集.rarVC++游戏开发特殊技巧实例源代码锦集.rarVC++游戏开发特殊技巧实例源代码锦集.rarVC++游戏开发特殊技巧实例源代码锦集.rarVC++游戏开发特殊技巧实例源代码锦集.rarVC++游戏...
总的来说,这个OpenGL实例源代码集合提供了一个全面的学习路径,帮助开发者从基础的图形绘制到复杂的3D场景模拟,逐步提升他们的OpenGL编程能力。通过实践这些代码,不仅可以巩固理论知识,还能锻炼实际编程技巧,为...
"Java经典编程实例源代码100例"提供了丰富的学习资源,特别适合初学者逐步进阶。这个资源包包含多个精心挑选的实例,覆盖了Java语言的各个核心概念和技术,旨在帮助开发者通过实践深入理解Java编程。 1. **实例6:...
在Android开发领域,掌握经典应用实例的源代码分析是提升技能的重要途径。这些实例源代码提供了深入了解Android应用程序设计、架构和实现细节的机会。本压缩包包含的7个经典Android应用程序实例,涵盖了Android开发...
总结起来,C#开发Skype API的应用实例源代码为我们提供了一个深入了解和掌握Skype API的宝贵平台。通过分析和实践这些代码,开发者可以提升自己在即时通讯应用开发领域的技能,为未来的项目打下坚实的基础。
C#WPF 语音实例源代码 亲测可用 tts(text to sound)开发教程 一步一步 教你制作语音软件 附图和源代码 . 详细教程程:http://blog.csdn.net/wyx100/article/details/43603419
在源代码中,"secs4net-master"可能是一个项目或库的主分支,暗示这是一个开源项目,名为"secs4net",专注于提供C#中的SECS和HSMS实现。通常,"master"分支代表项目的最新稳定版本。 使用这样的源代码实例,开发者...