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一下  :

 

105536_t5Hj_2338224.png

转载于:https://my.oschina.net/u/2338224/blog/968150

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值