RPC远程过程调用之 RMI实现

1)RMI(remote method invocation)是java原生支持的远程调用,RMI采用JRMP(java RemoteMessageing Protocol)作为通信协议。可以认为是纯java版本的分布式远程调用解决方法。

2)RMI的核心概念

3)RMI实现步骤

1、创建远程接口,并继承java.rmi.Remote接口

2、实现远程接口,并继承:UnicastRemoteObject

3、创建服务器程序,createRegistry() 方法注册远程对象

4、创建客户端程序,(获取注册信息,调用接口方法)

RMI_SERVER
 

package com.itheima.service;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface UserService extends Remote  {
    String sayHello(String name) throws RemoteException;
}

package com.itheima.service.impl;

import com.itheima.service.UserService;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class UserServiceImpl extends UnicastRemoteObject implements UserService {
    public UserServiceImpl() throws RemoteException {

    }

    @Override
    public String sayHello(String name) throws RemoteException {
        return name + "调用了服务端的sayHello方法";
    }
}
package com.itheima.server;

import com.itheima.service.UserService;
import com.itheima.service.impl.UserServiceImpl;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

public class ServerMain {
    public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {
        //启动RMI注册服务,指定端口号
        LocateRegistry.createRegistry(8888);
        //创建要被访问的远程对象的实例
        UserService userService = new UserServiceImpl();
        //将远程对象实例注册到RMI注册服务器上
        Naming.bind("rmi://127.0.0.1:8888/UserServer", userService);
        System.out.println("服务端启动中………………");
    }
}

RMI_CLIENT

package com.itheima.service;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface UserService extends Remote  {
    String sayHello(String name) throws RemoteException;
}

package com.itheima.client;

import com.itheima.service.UserService;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class ClientMain {
    public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException {
        UserService userService = (UserService) Naming.lookup("rmi://127.0.0.1:8888/UserServer");
        String s = userService.sayHello("客户端");
        System.out.println(s);


    }
}

注意:

client中Naming.lookup需要强转成UserService  此时的package路径要与server中的Userserver中的路径一致:

否则出现报错:

"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:D:\ruanjian\ideaiu14\ideaiu14\idea\IntelliJ IDEA 2020.1\lib\idea_rt.jar=63728:D:\ruanjian\ideaiu14\ideaiu14\idea\IntelliJ IDEA 2020.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;F:\RPC\RMI\rmi_client\target\classes" com.itheima.client.ClientMain
Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
	java.lang.ClassNotFoundException: com.itheima.service.UserService (no security manager: RMI class loader disabled)
	at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
	at java.rmi.Naming.lookup(Naming.java:101)
	at com.itheima.client.ClientMain.main(ClientMain.java:12)
Caused by: java.lang.ClassNotFoundException: com.itheima.service.UserService (no security manager: RMI class loader disabled)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:556)
	at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
	at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
	at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:265)
	at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1758)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1710)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2000)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	... 3 more

Process finished with exit code 1

运行结果:

需要先启动服端:
服务端启动中………………
客户端结果:

客户端调用了服务端的sayHello方法

 说明:在两个项目中,客户端成功的调用了服务器的sayHello()方法

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值