实现类共有5个:
com/chenun/javanet/rmi/RemoteCall.java | //RemoteCall类代表一次远程call的对象的抽象 |
com/chenun/javanet/rmi/RemoteServer.java | //远程方法调用服务器端 |
com/chenun/javanet/rmi/CallClient.java | //远程方法调用客户端 |
com/chenun/javanet/rmi/HelloService.java | //接口类 |
com/chenun/javanet/rmi/HelloServiceImpl.java | //实现类 |
RemoteCall.java
package com.chenun.javanet.rmi;
import java.io.Serializable;
import java.util.Arrays;
/**
* 一个RemoteCall对象表示一个客户端向一个服务端发起的一次远程调用
* @author Administrator
*2017年6月14日16:36:05
*/
public class RemoteCall implements Serializable
{
/**
* serialVersionUID
*/
private static final long serialVersionUID = -8214916480546311060L;
private String className; // 类名
private String methodName; // 方法名
private Class<?>[] paramTypes; // 参数类型
private Object[] params; // 参数列表
private Object result = null; // 方法执行结果
public RemoteCall()
{
}
public RemoteCall(String className, String methodName, Class<?>[] paramTypes, Object[] params)
{
this.className = className;
this.methodName = methodName;
this.paramTypes = paramTypes;
this.params = params;
}
public String getClassName()
{
return className;
}
public void setClassName(String className)
{
this.className = className;
}
public String getMethodName()
{
return methodName;
}
public void setMethodName(String methodName)
{
this.methodName = methodName;
}
public Class<?>[] getParamTypes()
{
return paramTypes;
}
public void setParamTypes(Class<?>[] paramTypes)
{
this.paramTypes = paramTypes;
}
public Object[] getParams()
{
return params;
}
public void setParams(Object[] params)
{
this.params = params;
}
public Object getResult()
{
return result;
}
public void setResult(Object result)
{
this.result = result;
}
@Override
public String toString()
{
return "RemoteCall [className=" + className + ", methodName=" + methodName + ", paramTypes=" + Arrays.toString(paramTypes)
+ ", params=" + Arrays.toString(params) + ", result=" + result + "]";
}
}
RemoteServer.java
package com.chenun.javanet.rmi;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class RemoteServer
{
//这个map存储className对应的Interface和实现类的对应关系
private Map<String,Object> remoteObjectMap = new HashMap<String,Object>(); //存放远程对象的缓存
private void register(String className,Object remoteObject)
{
remoteObjectMap.put(className, remoteObject);
}
public void service() throws IOException, ClassNotFoundException
{
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(8008, 100);
System.out.println("服务器端启动完毕...");
while(true)
{
Socket socket = serverSocket.accept();
//输入相关流
InputStream inputStream = socket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
//输出相关流
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
//接收remoteCall对象流
RemoteCall remoteCall = (RemoteCall)objectInputStream.readObject();
System.out.println(remoteCall.toString());
remoteCall = this.invoke(remoteCall);
//返回给远程客户端
objectOutputStream.writeObject(remoteCall);
this.release(inputStream);
this.release(outputStream);
this.release(socket);
}
}
private RemoteCall invoke(RemoteCall remoteCall)
{
Object result = null;
try
{
String className = remoteCall.getClassName();
String methodName = remoteCall.getMethodName();
Object[] params = remoteCall.getParams();
Class<?>[] paramTypes = remoteCall.getParamTypes();
/**
* Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,
* 也就是说JVM会执行该类的静态代码段
*/
Class<?> classType = Class.forName(className);
Method method = classType.getMethod(methodName, paramTypes);
Object remoteObject = remoteObjectMap.get(className);
if(remoteObject == null)
{
throw new ClassNotFoundException(className+"的远程对象不存在 ! ");
}
else
{
result = method.invoke(remoteObject, params);
}
}
catch(ClassNotFoundException e)
{
result = e;
e.printStackTrace();
}
catch (NoSuchMethodException e)
{
result = e;
e.printStackTrace();
}
catch (SecurityException e)
{
result = e;
e.printStackTrace();
}
catch (IllegalAccessException e)
{
result = e;
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
result = e;
e.printStackTrace();
}
catch (InvocationTargetException e)
{
result = e;
e.printStackTrace();
}
catch(Exception e)
{
result = e;
e.printStackTrace();
}
remoteCall.setResult(result);
return remoteCall;
}
private <T extends Closeable> void release(T t)
{
if(t != null)
{
try
{
t.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
RemoteServer remoteServer = new RemoteServer();
//把事先创建好的HelloServiceImpl加入到服务器缓存中
remoteServer.register("com.chenun.javanet.rmi.HelloService", new HelloServiceImpl());
try
{
remoteServer.service();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
CallClient.java
package com.chenun.javanet.rmi;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class CallClient
{
public void invoke() throws UnknownHostException, IOException, ClassNotFoundException
{
Socket socket = new Socket("localhost", 8008);
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
InputStream inputStream = socket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
//RemoteCall remoteCall = new RemoteCall("remotecall.HelloService", "getTime", new Class<?>[] {}, new Object[] { "test" });
RemoteCall remoteCall = new RemoteCall("com.chenun.javanet.rmi.HelloService", "echo", new Class<?>[] { String.class }, new Object[] { "test" });
objectOutputStream.writeObject(remoteCall);
RemoteCall call = (RemoteCall)objectInputStream.readObject();
System.out.println("call.getResult() = " + call.getResult());
this.release(outputStream);
this.release(inputStream);
this.release(socket);
}
public static void main(String[] args)
{
CallClient callClient = new CallClient();
try
{
callClient.invoke();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public <T extends Closeable> void release(T t)
{
if(t != null)
{
try
{
t.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
最后是接口+实现类:
HelloService.JAVA
package com.chenun.javanet.rmi;
import java.util.Date;
public interface HelloService
{
String echo(String msg);
Date getTime();
}
HelloServiceImpl.JAVA
package com.chenun.javanet.rmi;
import java.util.Date;
public class HelloServiceImpl implements HelloService
{
@Override
public String echo(String msg)
{
return "echo : "+msg;
}
@Override
public Date getTime()
{
return new Date();
}
}
RUN一下 :