您需要两个远程对象类。
第一个是通过Naming.lookup()
; 它是一个单例;它包含一个login()
方法。
此方法返回第二个远程对象,它不是单例,未在注册表中注册,并且为每个返回值重新创建。该对象包含所有银行业务方法以及一个logout()
取消导出它的方法;它可能还实现了Unreferenced
接口,因此它可以检测到死客户端,并自行取消导出。因为它每个客户端存在一次,它可以保存客户端状态,并且因为它只能通过成功的登录步骤获得,它解决了您的安全问题。
public interface Login extends Remote
{
Session login(String username, char[] password /* or whatever */)
throws LoginException, RemoteException;
}
public interface Session extends Remote
{
void logout() throws RemoteException;
void deposit(...) throws RemoteException;
void withdraw(...) throws RemoteException;
}
public class LoginImpl extends UnicastRemoteObject implements Login
{
public Session login(String username, char[] password)
throws LoginException, RemoteException
{
// username/password check; if it fails throw a LoginException
return new SessionImpl(username); // or whatever
}
}
public class SessionImpl extends UnicastRemoteObject implements Session, Unreferenced
{
public void logout() throws RemoteException
{
unexportObject(this, true);
}
public void unreferenced()
{
unexportObject(this, true); // needs to be in a try/catch block of course
}
// etc
}
我在 2001 年的书中将其描述为远程会话模式。
当然,您还需要传输层安全性:请参阅javax.rmi.ssl.