摘要: 远程接口发布在192.168.100.2服务器上。 服务端:192.168.100.2 客户端:192.168.100.1 服务器之前通讯正常。
在客户端编码:
<!-- lang: java -->
package com.itf;
import java.rmi.Remote; /**
- 远程接口定义
- @author gouwei
*/ public interface RMIInterFace extends Remote{ double add(double a,double b) throws java.rmi.RemoteException; double sub(double a,double b) throws java.rmi.RemoteException; double mul(double a,double b) throws java.rmi.RemoteException; double div(double a,double b) throws java.rmi.RemoteException;
}
package com.itf.impl;
import java.rmi.RemoteException;
import com.itf.RMIInterFace; /**
- 远程接口实现
- @author gouwei
*/ public class RMIImpl extends java.rmi.server.UnicastRemoteObject implements RMIInterFace{
private static final long serialVersionUID = 1L;
public RMIImpl() throws RemoteException {
super();
}
public double add(double a, double b) throws RemoteException {
return a+b;
}
public double sub(double a, double b) throws RemoteException {
return a-b;
}
public double mul(double a, double b) throws RemoteException {
return a*b;
}
public double div(double a, double b) throws RemoteException {
return a/b;
}
}
package com.server;
import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry;
import com.itf.RMIInterFace; import com.itf.impl.RMIImpl; /**
- 服务端注册
- @author gouwei
*/ public class RMIServer { public RMIServer(){
try {
RMIInterFace rmi = new RMIImpl();
//端口绑定
System. setSecurityManager(new java.rmi.RMISecurityManager());
LocateRegistry. createRegistry(4321);
Naming. bind("rmi://192.168.100.2:4321/RIMServer", rmi);
System. out.println(">>>>>> INFO:远程RMIServer绑定【192.168.100.2】成功!" );
} catch (RemoteException e) {
System. out.println("创建远程对象发生异常!" );
e.printStackTrace();
} catch (MalformedURLException e) {
System. out.println("重复绑定发生异常!" );
e.printStackTrace();
} catch (AlreadyBoundException e) {
System. out.println("URL异常!" );
e.printStackTrace();
}
}
public static void main(String args[]) {
new RMIServer();
}
}
package com.client;
import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException;
import com.itf.RMIInterFace; /**
- 客户端远程调用
- @author gouwei
*/ public class RMIClient {
public static void main(String[] args) {
try {
RMIInterFace rmi = (RMIInterFace)Naming.lookup("rmi://192.168.100.2:4321/RIMServer");
//add
System. out.println(rmi.add(10, 5));
//sub
System. out.println(rmi.sub(10, 5));
//mul
System. out.println(rmi.mul(10, 5));
//div
System. out.println(rmi.div(10, 5));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
编码完成之后,将编译后的客户端接口、接口实现类、服务端注册类、拷贝到192.168.100.2服务器上。 在C盘根目录编写安全策略文件 server.policy: grant{ permission java.net.SocketPermission "192.168.100.2:4321","accept,connect,resolve"; };
一、在192.168.100.2上执行命令: (1) start rmiregistry(windows) rmiregistry(linux) (2) cd到bin路劲执行:java com.itf.impl.RMIImpl 生成RMIImpl_Stub.class文件 (3) cd 到bin路劲执行:java -Djava.security.policy=C:\server.policy com.server.RMIServer 输出: C:\TestRMI_3\bin>java -Djava.security.policy=C:\server.policy com.server.RMIServer
INFO:远程RMIServer绑定【192.168.100.2】成功!
如果输出报错: C:\TestRMI_3\bin>java -Djava.security.policy=C:\server.policy com.server.RMIServ er Exception in thread "main" java.security.AccessControlException: access denied ( java.net.SocketPermission 192.168.100.2:4321 connect,resolve) at java.security.AccessControlContext.checkPermission(AccessControlConte xt.java:323) at java.security.AccessController.checkPermission(AccessController.java: 546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkConnect(SecurityManager.java:1034) at java.net.Socket.connect(Socket.java:513) at java.net.Socket.connect(Socket.java:469) at java.net.Socket.<init>(Socket.java:366) at java.net.Socket.<init>(Socket.java:180) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirect SocketFactory.java:22) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMaster SocketFactory.java:128) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198 ) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184) at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322) at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source) at java.rmi.Naming.bind(Naming.java:111) at com.server.RMIServer.<init>(RMIServer.java:20) at com.server.RMIServer.main(RMIServer.java:36)
【更改服务端C:\Program Files\Java\jdk1.6.0_10\jre\lib\security\java.policy 安全策略文件 在文件中加入server.policy中权限内容: permission java.net.SocketPermission "192.168.100.2:4321","accept,connect,resolve"; 或则 permission java.net.SocketPermission "*","accept,connect,resolve"; 然后重复3的操作即可。】 二、在客户端上执行:
(1) 保留远程接口和接口实现class,将生成RMIImpl_Stub.class文件拷贝到客户端“远程接口实现RMIImpl.class文件同级”。 (2) 运行客户度程序 cd到bin路劲下执行:java -Djava.security.policy=com.client.RMIClient 输出: F:\Workspaces\TestRMI_4\bin>java -Djava.security.policy= com.client.RMIClient 15.0 5.0 50.0 2.0
Spring RMI 配置
<!-- RMICLIENT CLIENT-SERVER -->
<bean id="serviceClient"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceInterface">
<value>com.qq.db.DBUser</value>
</property>
<!-- serviceUrl以rmi开头,定义服务器地址与端口和服务名 -->
<property name="serviceUrl" value="rmi://${servers.server}:${servers.port}/${server.serverName}" />
<property name="lookupStubOnStartup">
<value>false</value>
</property>
<property name="refreshStubOnConnectFailure">
<value>true</value>
</property>
</bean>