您的位置:首页 > 编程语言 > Java开发

JAVA反射+SOCKET实现远程方法调用

2017-06-16 00:00 711 查看
摘要: JAVA反射+SOCKET实现远程方法调用

实现类共有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一下 :

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  RMI socket