第一步:远程对象接口
WareHose.java
第二步:实现远程对象接口
第三步:将远程对象注册到RMI注册表中
第四步:创建客户端访问远程对象
第五步:启动RMI注册表(Window下)
在java安装路径下bin目录下有一个rmiregistry.exe服务
由于类:RegisterRmiServer.java在注册远程对象到RMI注册表中的时候rmiregistry需要加载远程对象的.class字节码文件,这里涉及到一个classpath的问题
[color=green]cmd>set classpath=%classpath%;远程对象的.class文件顶级包所在的目录
cmd>rmiregistry[/color]
上述命令要在同一个cmd窗口下执行
接下来可以用main方法测试效果
WareHose.java
package server;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface WareHose extends Remote{
public Double getPrice(String description)throws RemoteException;
}
第二步:实现远程对象接口
package server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
public class WareHoseImpl extends UnicastRemoteObject implements WareHose{
private static final long serialVersionUID = -5446129893581781406L;
private Map<String,Double> map = null;
public WareHoseImpl() throws RemoteException {
super();
map = new HashMap<String,Double>();
map.put("Apple", 6.5);
map.put("orange", 8.9);
//如果WareHoseImpl已经继承了其他的类可用在构造函数中使用
//UnicastRemoteObject.exportObject(this, 0);第二个参数0表示可在服务器任意端口上监听远程调用请求
}
@Override
public Double getPrice(String description) throws RemoteException {
return map.get(description);
}
}
第三步:将远程对象注册到RMI注册表中
package server;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class RegisterRmiServer {
private final static void register(String name,Object obj) throws NamingException{
Context namingContext = new InitialContext();
if(name != null)
//绑定的url格式为rmi://主机名:端口号/RMI注册对象的名称 次名称用于唯一表示远程对象客户端可通过此名称找到远程对象
//不写主机和端口号的话默认为localhost:1099
namingContext.bind("rmi:RemoteObject_"+name, obj);
else
namingContext.bind("rmi:"+obj.getClass().getSimpleName(), obj);
}
public final static void start(List<Object> list){
for(Object obj : list){
try {
register(null, obj);
} catch (NamingException e) {
e.printStackTrace();
}
}
}
public final static void start(Map<String,Object> map){
for(Entry<String, Object> entry : map.entrySet()){
try {
register(entry.getKey(), entry.getValue());
} catch (NamingException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception{
List<Object> list = new ArrayList<Object>();
WareHoseImpl wHose = new WareHoseImpl();
list.add(wHose);
RegisterRmiServer.start(list);
}
}
第四步:创建客户端访问远程对象
package client;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import server.WareHose;
public class AccessRemoteObject {
public static void main(String[] args) throws Exception{
Context namingContext = new InitialContext();
NamingEnumeration<NameClassPair> e = namingContext.list("rmi://localhost/");
while(e.hasMore()){
System.out.println(e.nextElement().getName());
}
WareHose wareHose = (WareHose)namingContext.lookup("rmi:WareHoseImpl");
System.out.println(wareHose.getPrice("orange"));
}
}
第五步:启动RMI注册表(Window下)
在java安装路径下bin目录下有一个rmiregistry.exe服务
由于类:RegisterRmiServer.java在注册远程对象到RMI注册表中的时候rmiregistry需要加载远程对象的.class字节码文件,这里涉及到一个classpath的问题
[color=green]cmd>set classpath=%classpath%;远程对象的.class文件顶级包所在的目录
cmd>rmiregistry[/color]
上述命令要在同一个cmd窗口下执行
接下来可以用main方法测试效果