Java之RMI(远程方法调用)

RMI(Remote Method Invocation)中文名称是远程方法调用,可用于分布式计算。

这里就不去详细介绍RMI了,本Blog主要讲叙RMI实战和有哪些需要注意的地方,如果想要查看详细介绍请查看:百度百科RMI

RMI分为服务端和客户端

服务端:

创建服务端:

LocateRegistry.createRegistry(端口);
Naming.rebind("rmi://IP地址:端口/RMI服务名称",RMI服务对象);//rebind也可以用bind替代

示例:

LocateRegistry.createRegistry(10010);
Naming.rebind("rmi://127.0.0.1:10010/Test", new TestServer());

RMI服务对象的类定义规则:

1.必须继承UnicastRemoteObject

2.构造方法必须声明抛出RemoteException

3.必须实现自定义的业务接口,不能直接实现Remote,必须将客户端要调用的接口抽取到接口中去

4.客户端要调用的接口方法返回值必须实现Serializable,虽然发布RMI服务时不会报错但RMI客户端调用此方法时会报错

RMI服务对象的接口定义规则:

1.接口必须继承Remote

2.接口方法必须声明抛出RemoteException

示例:

public interface TestServerInterface extends Remote {
    String getString() throws RemoteException;
    Student getStudent(String name) throws RemoteException;
}
public class TestServer extends UnicastRemoteObject implements TestServerInterface {
    public TestServer() throws RemoteException {
        super();
    }
    @Override
    public String getString() throws RemoteException {
        return System.currentTimeMillis()+":有客户端调用了此方法";
    }
    @Override
    public Student getStudent(String name) throws RemoteException {
        return new Student(name+System.currentTimeMillis());
    }
}

客户端:

创建并使用客户端:

RMI服务对象的接口 server= (RMI服务对象的接口) Naming.lookup("rmi://IP地址:端口/RMI服务名称");
返回值 result=server.你要调用的方法(可能需要传入的参数);

示例:

TestServerInterface serverInterface= (TestServerInterface) Naming.lookup("rmi://localhost:10010/Test");
System.out.println(">>>" + serverInterface.getString());
System.out.println(">>>" + serverInterface.getStudent("name1"));

RMI服务对象的接口定义规则:

1.可以和服务端定义的接口方法不一致,服务端有的这边可以没有,服务端没有的这边可以有,但调用时会报错

2.无须继承Remote,继承也行不过没意义

3.接口方法无须声明抛出RemoteException,声明抛出也行不过没意义

4.一般来说和服务端保持一致即可

示例:

public interface TestServerInterface {
    String getString();
    Student getStudent();
}

特别说明:

一、客户端使用的”RMI服务对象的接口”和服务端用”RMI服务对象的接口”是两个不用的类,因为客户端和服务端一般不在一台机器上。

二、如果客户端返回的值是自定义类型,客户端所定义接收的返回值则有下规则:

1.必须实现Serializable

2.如果服务端没有定义serialVersionUID,客户端这边也必须没有定义serialVersionUID

3.如果服务端有定义serialVersionUID,客户端这边也必须定义serialVersionUID并且serialVersionUID值要和服务端serialVersionUID值一致,否则会报未序列化和版本号不一致异常

示例1:

服务端返回自定义类型:

public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    public Student(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String toString(){
        return name;
    }
}

客户端接受自定义类型:

public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    public Student(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String toString(){
        return name;
    }
}

示例2:

服务端返回自定义类型:

public class Student implements Serializable {
    private String name;
    public Student(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String toString(){
        return name;
    }
}

客户端接受自定义类型:

public class Student implements Serializable {
    private String name;
    public Student(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String toString(){
        return name;
    }
}

完整代码:

项目图:

服务端:

package test;

import java.io.Serializable;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;

public class RmiServerMain {
    public static void main(String[] args) throws Exception {
        LocateRegistry.createRegistry(10010);
        Naming.bind("rmi://127.0.0.1:10010/Test", new TestServer());
    }
}

interface TestServerInterface extends Remote {

    String getString() throws RemoteException;

    Student getStudent(String name) throws RemoteException;
}

class TestServer extends UnicastRemoteObject implements TestServerInterface {

    private static final long serialVersionUID = 1L;

    public TestServer() throws RemoteException {
        super();
    }

    @Override
    public String getString() throws RemoteException {
        return System.currentTimeMillis() + ":有客户端调用了此方法";
    }

    @Override
    public Student getStudent(String name) throws RemoteException {
        return new Student(name + System.currentTimeMillis());
    }
}

class Student implements Serializable {

    private static final long serialVersionUID = 110L;

    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public String toString() {
        return getClass().getSimpleName() + ":name=" + name;
    }
}

客户端

package test;

import java.io.Serializable;
import java.rmi.Naming;

public class RmiClientMain {
    public static void main(String[] args) throws Exception {
        TestServerInterface serverInterface = (TestServerInterface) Naming.lookup("rmi://127.0.0.1:10010/Test");
        System.out.println(">>>" + serverInterface.getString());
        System.out.println(">>>" + serverInterface.getStudent("StuName"));
    }
}

/**
 * 客户端的服务接口,不是必须继承Remote,并且方法不是必须申明抛出RemoteException<br>
 * 但包名、类名必须要和服务端完全一致。<br>
 * 方法可以删掉、可以乱加,但乱加的方法你只要不调用就行,以调用就报错。<br>
 * 方法的结构不同改,如返回类型,参数类型。
 *
 * @author Tang
 *
 */
interface TestServerInterface {

    String getString();

    Student getStudent(String name);
}

class Student implements Serializable {

    /**
     * serialVersionUID变量必须和服务端保持一致。<br>
     * 如果服务端没有定义此变量,客户端这里也必须不要定义此变量<br>
     * 如果服务端有定义此变量,客户端这里也必须要定义此变量,并且变量的值也要相同
     */
    private static final long serialVersionUID = 110L;

    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public String toString() {
        return getClass().getSimpleName() + ":name=" + name;
    }
}
时间: 2024-11-10 10:41:04

Java之RMI(远程方法调用)的相关文章

Java的RMI远程方法调用实现和应用

最近在学习Dubbo,RMI是很重要的底层机制,RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机(即JVM虚拟机)上的对象可以调用另外一台计算机上的对象来获取远程数据. RMI的实现对建立分布式Java应用程序至关重要,是Java体系非常重要的底层技术. 1.RMI的概念和原理 RMI思路是在客户端安装一个代理(proxy),代理是位于客户端虚拟机中的一个对象,对于客户端对象,看起来就

Java RMI(远程方法调用) 实例与分析 (转)

目的: 通过本文,可以加深对Java RMI的理解,知道它的工作原理,怎么使用等. 也为了加深我自己的理解,故整理成文.不足之处,还望指出. 概念解释: RMI(RemoteMethodInvocation):远程方法调用,顾名思义,通过远程的方式调用非本地对象的方法并返回结果.使用远程调用通常解决本地计算瓶颈问题,例如分布式记算,最近很火的阿尔法狗人机大战,据说运算使用上千个CPU. JRMP(java remote method protocol):java远程方法协议,这是完成java到j

Java之——RMI远程过程调用(插曲)

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/45970641 一.定义          Java RMI:Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远程服务器上的对象.远程方法调用特性使Java编程人员能够在网络环境中分布操作.RMI全部的宗旨就是尽可能简化远程接口对象的

JAVA RMI远程方法调用简单实例[转]

RMI的概念 RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机上的对象可以调用另外 一台计算机上的对象来获取远程数据.RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径.在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对 象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote

Java中RMI远程调用demo

Java远程方法调用,即Java RMI(Java Remote Method Invocation),一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远程服务器上的对象.远程方法调用特性使Java编程人员能够在网络环境中分布操作.RMI全部的宗旨就是尽可能简化远程接口对象的使用. Java RMI极大地依赖于接口.在需要创建一个远程对象的时候,程序员通过传递一个接口来隐藏底层的实现细节.客户端得到的远程对象句柄正好与本地的根代码连接,由后者负责透过网络通信.这样一来,

RMI远程方法调用技术

RMI是J2EE技术规范之一,英文全称Remote Method Invocation(即远程方法调用).远程方法调用是一种同一计算机不同Java研发软件系统之间或不同计算机不同Java研发软件系统之间通过调用对方远程方法启动对方进程进而实现交互的一种机制,这种机制为开发分布式应用程序带来了极大的方便. RMI技术的应用通常包括在两个独立的应用程序中:服务端应用程序和客户端应用程序. 服务端应用程序: RMI典型的服务端代码将创建多个远程对象,使这些远程对象能够被引用,然后等待客户端调用这些远程

关于&lt;Java 中 RMI、JNDI、LDAP、JRMP、JMX、JMS那些事儿(上)&gt;看后的一些总结-1

原文地址:https://www.anquanke.com/post/id/194384#h3-3 1.java rmi 关于rmi客户端和服务端通信的过程,java的方法都实现在rmi服务端,客户端实际上是通过访问rmi注册表拿到stub,然后再通过它调用服务端方法,那么调用方法时要传递参数,参数可以为一般类型,也可以为引用类型,那么如果为引用类型,就能够利用服务端已经有的gaget chain来打server,因为参数实际上是序列化传输的,那么数据到达服务端后必定会经过反序列化. 客户端:

java RMI入门指南

感觉这篇文章不错,直接转了 RMI全称是Remote Method Invocation-远程方法调用,Java RMI在JDK1.1中实现的,其威力就体如今它强大的开发分布式网络应用的能力上,是纯Java的网络分布式应用系统的核心解决方式之中的一个.事实上它能够被看作是RPC的Java版本号.可是传统RPC并不能非常好地应用于分布式对象系统.而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信.实现远程对象之间的无缝远程调用. RMI眼下使用Java远程消息交换协议JRMP

对JAVA RMI的认识

RMI的定义 RPC (Remote Procedure Call):远程方法调用,用于一个进程调用另一个进程中的过程,从而提供了过程的分布能力. RMI(Remote Method Invocation):远程方法调用,即在RPC的基础上有向前迈进了一步,提供分布式对象间的通讯.允许运行在一个java 虚拟机的对象调用运行在另一个java虚拟机上对象的方法.这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中. RMI的全称宗旨就是尽量简化远程接口对象的调用.