1、问题的描述
本例子模拟了一个远程请求对象访问属性的过程。有一个远程对象Dog在网络上,现在要得到它的名字(strName)属性的服务。
2、实现的机制
(1)程序在客户端设有一个存根类(Dog_Stub,该类实现客户端的请求代理),在服务器端启动一个骨架类(dog_Skeleton,该类实现服务器端的响应代理),这两个类都实现了Dog接口,Dog_Stub与Dog_Skeleton通过Socket进行网络远程通信。
(2)当客户程序DogClient向Dog_Stub发出获取名字属性的请求时,Dog_Stub对象把方法名“getName()”作为一个字符串通过Socket发给远程的Dog_Skeleton对象,Dog_Skeleton对象收到这个字符串后再根据字符串的内容执行DogServer对象的getName()方法,得到Dog的名字,然后又通过Socket返回给DogStub对象。
(3)整个流程通过网络实现,但对于客户程序DogClient来讲,它并不知道真正的Dog对象在哪里,甚至也不知道这个过程通过了网络,它只知道发出的获取名字属性的请求得到了满意的结果而已。
3、各个部分的程序代码
(1)Dog接口的定义Dog.java
public interface Dog
{
public String getName() throws Exception;
}
(2)Dog服务器程序类,它提供向客户端提供“查询”狗的名称“TOMCAT”的服务
public class DogServer implements Dog
{
String strName;
int intAge;
public String getName() throws Exception
{
return strName;
}
public DogServer( String strNameInput )
{
strName = strNameInput;
}
public static void main( String[] args ) throws Exception
{
new Dog_Skeleton(new DogServer("TOMCAT")); //狗的名称为"TOMCAT"
}
}
(3)服务端骨架类程序,它是服务端的代理对象。该类通过Socket获得客户端Dog_Stub请求代理所发来的“业务方法”请求,然后去访问服务器类中的方法,获得结果。然后再通过Socket向客户端Dog_Stub输出业务结果。
import java.io.*;
import java.net.*;
public class Dog_Skeleton extends Thread
{
static ServerSocket ss = null;
DogServer ds;
public Dog_Skeleton( DogServer dsInput ) throws Exception
{
ds = dsInput;
if ( ss == null )
ss = new ServerSocket( 8000 );
this.start();
}
public synchronized void run()
{
try
{
while ( ss != null )
{
Socket socket = ss.accept();
ObjectInputStream ois = new ObjectInputStream( socket.getInputStream() );
ObjectOutputStream oos = new ObjectOutputStream( socket.getOutputStream() );
String strMethodName = ( String )ois.readObject();
if ( strMethodName.equals( "getName()" ) )
oos.writeObject( ds.getName() ); //获得业务结果并返回给客户代理
oos.flush();
ois.close();
oos.close();
socket.close();
}//while
}//try
catch( Exception e )
{
e.printStackTrace();
}//catch
}//run()
}
(4)客户端的存根(Dog_Stub)类
import java.io.*;
import java.net.*;
public class Dog_Stub implements Dog
{
Socket socket;
ObjectOutputStream oos;
ObjectInputStream ois;
public Dog_Stub() throws Exception
{
socket = new Socket( "127.0.0.1", 8000 );
oos = new ObjectOutputStream( socket.getOutputStream() );
ois = new ObjectInputStream( socket.getInputStream() );
}
public String getName() throws Exception
{
oos.writeObject( "getName()" );
oos.flush();
return ( String )ois.readObject();
}
}
(5)客户端请求狗的名称的类,该类为客户机的业务功能请求类。该业务功能请求并不是由客户直接向服务器发出的,而是通过客户端Dog_Stub请求代理来发送。
这样客户端只是一个简单的请求者,从而可以实现瘦客户机效果。
public class DogClient
{
public static void main( String[] args ) throws Exception
{
Dog dog = new Dog_Stub();
String strName = dog.getName();
System.out.println( "从服务器端获得的狗的名称为:" + strName );
}
}
(6)执行的结果
执行 DogClient.java和DogServer.java程序两程序