Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。 相对于cxf等Web Service的实现,rmi显得相对轻巧,RMI也是最简单的,在一些小的应用中是最合适的。
缺点:1.RMI对服务器的IP地址和端口依赖很紧密,但是在开发的时候不知道将来的服务器IP和端口如何,但是客户端程序依赖这个IP和端口。 这个问题有两种解决途径:一是通过DNS来解决,二是通过封装将IP暴露到程序代码之外。
2.RMI是Java语言的远程调用,两端的程序语言必须是Java实现。
开始第一个demo:
第一步:定义接口
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Map;
import com.Rmi.Model.Student;
import com.Rmi.Model.StudentResponse;
/**
* 构造一个返回各种复杂对象的测试
* 1. List
* 2.Map
* 3.Array
* 3.Object
* @author Administrator
*
*/
public interface IStudentMsg extends Remote {
/**
* 获得student 的list集合
* @return
*/
public List<Student> findStudents() throws RemoteException; ;
/**
* 获得student相关的map类型
* @return
*/
public Map<String,String> findStudentMap() throws RemoteException; ;
/**
* 返回数组形式
* @return
*/
public Student[] findStudentArray() throws RemoteException; ;
/**
* 返回一个比较复杂的类型
* @return
*/
public StudentResponse findStudentClassMates() throws RemoteException; ;
}
第二步,实现类
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.Rmi.Imp.IStudentMsg;
import com.Rmi.Model.Student;
import com.Rmi.Model.StudentResponse;
public class StudentMsg extends UnicastRemoteObject implements IStudentMsg{
public StudentMsg() throws RemoteException {
super();
}
private static final long serialVersionUID = 449315607221300521L;
@Override
public List<Student> findStudents() {
List<Student> list = new ArrayList<Student>();
list.add(new Student("tABCD","高二"));
list.add(new Student("ABCD","高二"));
return list;
}
@Override
public Map<String, String> findStudentMap() {
Map<String,String> map = new HashMap<String ,String>();
map.put("1", "tssss");
map.put("2", "ddddd");
return map;
}
@Override
public Student[] findStudentArray() {
Student[] students = new Student[3];
students[0]=new Student("ABCD","构思");
students[1]=new Student("ABCD","gaosan");
return students;
}
@Override
public StudentResponse findStudentClassMates() {
StudentResponse respon = new StudentResponse();
respon.setName("ABCD");
List<Student> list = new ArrayList<Student>();
list.add(new Student("ABCD","高二"));
list.add(new Student("涂ABCD","高二"));
respon.setClassMates(list);
return respon;
}
}
第三步:发布服务
IStudentMsg rstudent = new StudentMsg();
//本地主机上的远程对象注册表Registry的实例,并指定端口为8888,这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上
LocateRegistry.createRegistry(8888);
//把远程对象注册到RMI注册服务器上,并命名为rstudent
//绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略)
Naming.bind("rmi://localhost:8888/RStudentMsg",rstudent);
System.out.println(">>>>>INFO:远程rstudent对象绑定成功!");
第四步:客户端
public class RmiClient{
public static void main(String args[]){
try {
IStudentMsg studentMsg =(IStudentMsg) Naming.lookup("rmi://localhost:8888/RStudentMsg");
System.out.println(studentMsg.findStudentArray()[0].getClassName());
System.out.println(studentMsg.findStudentClassMates().name);
System.out.println(studentMsg.findStudentMap().get("1"));
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}