Catalina 通过Manager接口支持会话管理,一个Manager与一个context关联,Manager负责创建 更新 销毁session对象,也返回合格的对象给请求组件。
Servlet可以通过调用ServletRequest 接口的getSession方法获得一个session。
我们看一下实现了这个接口的HttpRequestBase 类。
public HttpSession getSession() {
return (getSession(true));
}
public HttpSession getSession(boolean create) {
...
return doGetSession(create);
}
private HttpSession doGetSession(boolean create) {
// There cannot be a session if no context has been assigned yet
if (context == null)
return (null);
// Return the current session if it exists and is valid
if ((session != null) && !session.isValid())
session = null;
if (session != null)
return (session.getSession());
// Return the requested session if it exists and is valid
Manager manager = null;
if (context != null)
manager = context.getManager();
if (manager == null)
if (manager == null)
return (null);
// Sessions are not supported
if (requestedSessionId != null) {
try {
session = manager.findSession(requestedSessionId);
}
catch (IOException e) {
session = null;
}
if ((session != null) && !session.isValid())
session = null;
if (session != null) {
return (session.getSession());
}
}
// Create a new session if requested and the resp
// committed
if (!create)
return (null);
...
session = manager.createSession();
if (session != null)
return (session.getSession());
else
return (null);
}
默认,manager把它的session对象放在内存中,tomcat也允许manager通过jdbc持久化到数据库中。
Sessions
在servlet编程中,session代表HttpSession接口,这个接口的实现类StandardSession基于安全的考虑,manager不会传递它的实例给servlet,而是用StandardSessionFacade来代替。
session接口
Listing 9.1: The Session interface
package org.apache.catalina;
import java.io.IOException;
import java.security.Principal;
import java.util.Iterator;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
public interface Session {
public static final String SESSION_CREATED_EVENT = "createSession";
public static final String SESSION_DESTROYED_EVENT =
"destroySession";
public String getAuthType();
public void setAuthType(String authType);
public long getCreationTime();
public void setCreationTime(long time);
public String getId();
public void setId(String id);
public String getInfo();
public long getLastAccessedTime();
public Manager getManager();
public void setManager(Manager manager);
public int getMaxInactiveInterval();
public void setMaxInactiveInterval(int interval);
public void setNew(boolean isNew);
public Principal getPrincipal();
public void setPrincipal(Principal principal);
public HttpSession getSession();
public void setValid(boolean isValid);
public boolean isValid();
public void access();
public void addSessionListener(SessionListener listener);
public void expire();
public Object getNote(String name);
public Iterator getNoteNames();
public void recycle();
public void removeNote(String name);
public void removeSessionListener(SessionListener listener);
public void setNote(String name, Object value);
}
一个session对象一定包含一个manager,在context中,session有唯一的标示联系到它的manager。
StandardSession类
The getSession 方法创建了一个StandardSessionFacade对象:
@Override
public HttpSession getSession() {
if (facade == null){
if (SecurityUtil.isPackageProtectionEnabled()){
final StandardSession fsession = this;
facade = AccessController.doPrivileged(
new PrivilegedAction<StandardSessionFacade>(){
@Override
public StandardSessionFacade run(){
return new StandardSessionFacade(fsession);
}
});
} else {
facade = new StandardSessionFacade(this);
}
}
return (facade);
}
StandardManager类
Manager的标准实现,将session储存与内存中,实现了lifeCycle接口,它可以被启动和停止。