rmi实例讲解(转载)
这里用到了 Java RMI (Remote Method Invocation)
Java RMI是一种机制, 是能够让一个 java虚拟机 调用 另一个java 虚拟机上对象的方法, 从而实现远程访问.
但是通过客户端实现该远程访问 必须绑定一个远程接口对象.
定义远程接口
首先 我们写个远程接口 HelloInterface 该接口继承了远程对象Remote
接口HelloInterface 里面有个sayHello的方法 用于客户端连接后 打招呼
由于sayHello方法 继承了远程Remote对象 所以需要抛一个 RemoteException 远程异常。
package Remote_Interface;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 接口HelloInterface 继承了 远程接口 Remote 用于客户端Client远程调用
* @author SoFlash - 博客园 http://www.cnblogs.com/longwu
*/
public interface HelloInterface extends Remote{
public String sayHello(String name) throws RemoteException;
}
实现接口(实现接口在服务端)
接下来 我们实现下 该接口里的方法 实现接口的方法在服务端
通过 HelloInterfaceImpl类 实现了接口HelloInterface里的方法
注意: 这里HelloInterfaceImpl 同样继承了 UnicastRemoteObject 远程对象 这个必须写 虽然不写 代码智能提示不会提示有错 但服务器启动后会报错
由于 UnicastRemoteObject 远程对象 需要抛出一个RemoteException 异常 所以 这里用了一个构造方法 HelloInterfaceImpl() 来抛这个异常。
package Server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import Remote_Interface.HelloInterface;
/**
* HelloInterfaceImpl 用于实现 接口HelloInterface 的远程 SayHello方法
* @author SoFlash - 博客园 http://www.cnblogs.com/longwu
*/
@SuppressWarnings("serial")
// 继承 UnicastRemoteObject 远程对象 这个一定要写 否则 服务器启动报异常
public class HelloInterfaceImpl extends UnicastRemoteObject implements HelloInterface{
//HelloInterfaceImpl的构造方法 用于抛出UnicastRemoteObject 远程对象里的异常
protected HelloInterfaceImpl() throws RemoteException {
}
public String sayHello(String name) throws RemoteException {
//该信息 在客户端上发出
String strHello = "你好! " + name+" 欢迎访问服务器!";
//这条信息 是在服务器上 打印出来
System.out.println(name +" 正在 访问本服务器!");
return strHello;
}
}
编写服务端
接下来 我们来写 服务端 由于RMI 实现远程访问的机制是指 客户端通过在RMI注册表上寻找远程接口对象的地址(服务端地址) 达到实现远程访问的目的
所以这里 我们需要在 服务端 创建一个远程对象的注册表 用于绑定和注册 服务器端地址和远程接口对象 便于后期客户端能够成功找到服务端 (详细请看代码注释)
package Server;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import Remote_Interface.HelloInterface;
/**
* Server 类 用于 启动 注册服务器
* @author SoFlash - 博客园 http://www.cnblogs.com/longwu
*/
public class Server {
public static void main(String[] args) {
try {
// 定义远程接口HelloInterface 对象 用于绑定在服务器注册表上 该接口由HelloInterfaceImpl()类实现
HelloInterface hInterface = new HelloInterfaceImpl();
int port = 6666; // 定义一个端口号
// 创建一个接受对特定端口调用的远程对象注册表 注册表上需要接口一个指定的端口号
LocateRegistry.createRegistry(port);
// 定义 服务器远程地址 URL格式
String address = "rmi://localhost:" + port + "/hello";
// 绑定远程地址和接口对象
Naming.bind(address,hInterface);
// 如果启动成功 则弹出如下信息
System.out.println(">>>服务器启动成功");
System.out.println(">>>请启动客户端进行连接访问");
} catch (MalformedURLException e) {
System.out.println("地址出现错误!");
e.printStackTrace();
} catch (AlreadyBoundException e) {
System.out.println("重复绑定了同一个远程对象!");
e.printStackTrace();
} catch (RemoteException e) {
System.out.println("创建远程对象出现错误!");
e.printStackTrace();
}
}
}
编写客户端
服务器写完了 我们来写下访问服务器需要的客户端
客户端上同样 需要定义一个 远程访问的地址 - 即服务器地址
然后 通过在RMI注册表上寻找 该地址; 如果找到 则建立连接。
package Client;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import Remote_Interface.HelloInterface;
/**
* Client 用于连接 并访问 服务器Server
* @author SoFlash - 博客园 http://www.cnblogs.com/longwu
*/
public class Client {
public static void main(String[] args) {
// 定义一个端口号 该端口号必须与服务器的端口号相同
int port = 6666;
// 同样定义一个远程地址 该地址为服务器的远程地址 所以 与服务器的地址是一样的
String address = "rmi://localhost:" + port + "/hello";
// 在RMI注册表上需找 对象为HelloInterface的地址 即服务器地址
try {
HelloInterface hInterface = (HelloInterface) Naming.lookup(address);
// 一旦客户端找到该服务器地址 则 进行连接
System.out.println("<<<客户端访问成功!");
//客户端 Client 调用 远程接口里的 sayHello 方法 并打印出来
System.out.println(hInterface.sayHello("SoFlash"));
} catch (MalformedURLException e) {
System.out.println("错误的地址!");
e.printStackTrace();
} catch (RemoteException e) {
System.out.println("创建远程对象出错!");
e.printStackTrace();
} catch (NotBoundException e) {
System.out.println("未绑定的远程对象!");
e.printStackTrace();
}
}
}