`
dicmo
  • 浏览: 68527 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Coder 爱翻译 How Tomcat Works 第九章 第一部分

    博客分类:
  • j2ee
阅读更多
Chapter 9: Session Management

Catalina通过一个叫做manager的组件来支持session管理。manager是由org.apache.catalina.Manager接口表示。一个manager总是和一个context相关联的。manager负责创建、更新、销毁(使一个session失效)session对象和返回一个有效的session对象给请求组件。

servlet可以通过调用javax.servlet.http.HttpServletRequest接口的getSession方法来获取一个session对象。在默认连接器中org.apache.catalina.connector.HttpRequestBase类实现了HttpServletRequest接口。
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) 
      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 response is not 
   // committed 
   if (!create) 
     return (null); 
   ...
    session = manager.createSession(); 
    if (session != null) 
      return (session.getSession()); 
    else 
      return (null); 
}

默认情况下,manager把它的session对象存储在内存中。但是,Tomcat也可以允许manager把它的session对象持久化到存储文件或数据库中。Catalina提供org.apache.catalina.session包,这个包中包含了session对象相关的类型和session管理。

这章分三部分:"Sessions", "Managers"和"Stores"。

Sessions

在servlet编程中,一个session对象由javax.servlet.http.HttpSession接口表示。这个接口的实现是org.apache.catalina.session包下的StandardSession类。但是,出于安全考虑,manager不会传递一个StandardSession实例给一个servlet。它使用在org.apache.catalina.session包下面的facade类:StandardSessionFacade。在内部,管理器与另外一个facade:org.apache.catalina.Session一起工作。类图:



The Session Interface

Session接口作为一个Catalina内部的façade。Session接口的标准实现是StandardSession。
StandardSession也实现了javax.servlet.http.HttpSession接口。
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里面的。setManager和getManager方法用来把一个Session实例和一个manager相关联起来。一个Session实例也有一个唯一的标识符。可以使用setId和getId方法来访问Session的标识符。manager调用getLastAccessedTime方法来确定一个Session对象是否合法有效。manager调用setValid和reset方法来设置和重新设置一个session对象为合法有效。每次一个Session实例被访问,它的access方法被调用来修改它的最后被访问时间(last accessed time)。最后,manager可以调用它的expire方法把一个session设为超时。getSession方法返回一个被这个facade包装后的HttpSession对象。

The StandardSession Class

StandardSession类是Session接口的标准实现。它除了实现了javax.servlet.http.HttpSession 和org.apache.catalina.Session,还实现了java.lang.Serializable让Session对象可以被序列化。

这个类的构造函数接收一个Manager实例,使一个Session对象总是有一个对应的Manager。
public StandardSession(Manager manager);

下面是一些重要的private变量。注意transient关键字修饰的变量不会被序列化。
// session attributes 
private HashMap attributes = new HashMap(); 
// the authentication type used to authenticate our cached Principal, 
private transient String authType = null; 
private long creationTime = 0L; 
private transient boolean expiring = false; 
private transient StandardSessionFacade facade = null; 
private String id = null; 
private long lastAccessedTime = creationTime; 
// The session event listeners for this Session. 
private transient ArrayList listeners = new ArrayList(); 
private Manager manager = null; 
private int maxInactiveInterval = -1; 
// Flag indicating whether this session is new or not. 
private boolean isNew = false; 
private boolean isValid = false; 
private long thisAccessedTime = creationTime;

注意在Tomcat 5中,上面的变量是protected修饰的。每个变量都有一对get/set方法。

getSession方法通过传递这个实例来创建一个StandardSessionFacade对象。
public HttpSession getSession() { 
   if (facade == null) 
     facade = new StandardSessionFacade(this); 
   return (facade); 
}

一个Session对象在一段时间内(超过了Manager里的maxInactiveInterval变量的值)没有被访问。它将被设置为超时过期。让一个Session对象超时过期,调用Session接口的expire方法。
Listing 9.2: The expire method   
 
public void expire(boolean notify) { 
   // Mark this session as "being expired" if needed 
   if (expiring) 
     return; 
   expiring = true; 
   setValid(false);
// Remove this session from our manager's active sessions 
   if (manager != null) 
     manager.remove(this); 
   // Unbind any objects associated with this session 
   String keys [] = keys(); 
   for (int i = 0; i < keys.length; i++) 
     removeAttribute(keys[i], notify); 
   // Notify interested session event listeners 
   if (notify) { 
     fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null); 
   } 
   // Notify interested application event listeners 
   // FIXME - Assumes we call listeners in reverse order 
   Context context = (Context) manager.getContainer(); 
   Object listeners[] = context.getApplicationListeners(); 
   if (notify && (listeners != null)) { 
     HttpSessionEvent event = new HttpSessionEvent(getSession()); 
     for (int i = 0; i < listeners.length; i++) { 
       int j = (listeners.length - 1) - i; 
       if (!(listeners[j] instanceof HttpSessionListener)) 
         continue;
       HttpSessionListener listener = 
        (HttpSessionListener) listeners[j]; 
       try { 
         fireContainerEvent(context, "beforeSessionDestroyed", 
           listener); 
         listener.sessionDestroyed(event); 
         fireContainerEvent(context, "afterSessionDestroyed", listener); 
       } 
       catch (Throwable t) { 
         try { 
           fireContainerEvent(context, "afterSessionDestroyed", 
             listener); 
         } 
         catch (Exception e) { 
           ; 
         } 
         // FIXME - should we do anything besides log these?
         log(sm.getString("standardSession.sessionEvent"), t); 
       } 
     }
   } 
// We have completed expire of this session 
   expiring = false; 
   if ((manager != null) && (manager instanceof ManagerBase)) { 
     recycle(); 
   } 
}

超时处理包括了设置一个叫做expiring的内部变量、从Manager中移除Session实例和触发一些事件。

The StandardSessionFacade Class

要把一个Session对象传递给servlet,Catalina要实例化StandardSession类,填充属性,然后把它传递给servlet。它传递给一个StandardSessionFacade实例,只提供了在javax.servlet.http.HttpSession的方法实现。这样,servlet程序员就不能把HttpSession对象向下转型成StandardSessionFacade类,访问它的public方法。

Manager

manager管理是session对象的。例如:它创建session对象和让session对象失效。manager是由org.apache.catalina.Manager接口表示的。在Catalina中,org.apache.catalina.session包中包含了ManagerBase类,它提供了通用的功能的实现。ManagerBase有两个直接的子类:StandardManager和PersistentManagerBase。

当应用程序运行是时,StandardManager把session对象存储在内存中。当应用程序停止了,它把就当前在内存中所有的session对象存储到一个文件中去。当再次启动应用程序时,在从文件中把session对象加载进内存。

PersistentManagerBase类是manager组件的基类,它把session对象存储到辅助存储器里面。它有两个子类:PersistentManager和DistributedManager(DistributedManager只在Tomcat 4中),类图:



The Manager Interface

Manager接口代表了一个Manager组件:
Listing 9.3: The Manager interface   
 
package org.apache.catalina; 
import java.beans.PropertyChangeListener; 
import java.io.IOException; 
 
public interface Manager { 
   public Container getContainer(); 
   public void setContainer(Container container); 
   public DefaultContext getDefaultContext(); 
   public void setDefaultContext(DefaultContext defaultContext); 
   public boolean getDistributable(); 
   public void setDistributable(boolean distributable); 
   public String getInfo(); 
   public int getMaxInactiveInterval(); 
   public void setMaxInactiveInterval(int interval); 
   public void add(Session session); 
   public void addPropertyChangeListener(PropertyChangeListener listener);
   public Session createSession(); 
   public Session findSession(String id) throws IOException;
   public Session[] findSessions(); 
   public void load() throws ClassNotFoundException, IOException; 
   public void remove(Session session); 
   public void removePropertyChangeListener(PropertyChangeListener listener); 
   public void unload() throws IOException; 
} 

首先,Manager接口用getContainer 和setContainer方法把Manager的实现和一个context相关联起来。createSession方法创建一个Session对象。add方法把一个Session实例添加到session池中。remove方法把Session对象从session池中移除。getMaxInactiveInterval和setMaxInactiveInterval方法返回和指定Manager将要等待用户拥有一个与该用户相关联的session的指定秒数。超过这个时间秒数,Manager将销毁这个session,即该session失效了。

最后,在Manager实现里支持一种持久化机制。load和unload方法支持把session持久化存储到辅助存储器。通过这个Manager实现,unload方法把当前活动的session存储到指定的存储地方。load方法把已被持久化的session重新加载到内存中去。
  • 大小: 20.3 KB
  • 大小: 33 KB
1
1
分享到:
评论

相关推荐

    tomcat原理解析书(how-tomcat-works)中文版

    适合读者 1.jsp/servlet 开发人员,想了解 tomcat 内部机制的 coder; 2.想加入 tomcat 开发团队的 coder; 3.web 开发人员,但对软件开发很有兴趣的 coder; 4.想要对 tomcat 进行定制的 coder。

    Bad Programming Practices 101 Become a Better Coder by Learning How (Not) epub

    Bad Programming Practices 101 Become a Better Coder by Learning How (Not) to Program 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书

    phpcoder.rar

    PHPCoder是一款专为PHP开发者设计的高效代码编辑器,旨在提供一个轻量级且功能丰富的开发平台。这款软件以其便捷性、易用性和强大的功能深受程序员喜爱。在本篇文章中,我们将深入探讨PHPCoder的各项特性、安装过程...

    mediacoder专业版

    mediacoder 5685专业版,无普通版的限制

    MediaCoder答题器

    6. 插件扩展:MediaCoder有一个开放的插件架构,用户可以通过安装第三方插件来增加新的编码解码器、滤镜和其他功能,扩展其应用范围。 7. 用户友好:MediaCoder的界面简洁直观,即便是对编码不熟悉的用户也能快速...

    simulink hdl coder 用户手册pdf

    综上所述,Simulink HDL Coder 作为一款先进的工具,极大地简化了从算法设计到 FPGA 实现的整个过程,是现代电子设计自动化领域不可或缺的一部分。通过掌握其使用方法和技术要点,工程师们能够更高效地完成复杂的 ...

    matlab Embedded Coder Getting Started Guide.pdf

    Embedded Coder用于产生嵌入式处理器、目标快速原型板和大规模生产中使用的微处理器的可读的、紧凑的、快速的C和C++代码。Embedded Coder支持附加的MATLAB Coder™和Simulink Coder™配置选项,以及对生成代码的功能...

    Mediacoder基础教程

    Mediacoder是一款强大的多媒体编码工具,专为音频和视频转换而设计,支持多种格式,如MP4、AVI、MKV等。本教程将深入讲解如何利用Mediacoder进行视频压制,优化视频质量,同时合理权衡码率与视频大小的关系。 **1. ...

    The Clean Coder

    Martin, "The Clean Coder: A Code of Conduct for Professional Programmers" Prentice Hall | 2011 | ISBN: 0137081073 | 256 pages | PDF | 6 MB Programmers who endure and succeed amidst swirling ...

    CoolCoder 类生成工具

    虽然CoolCoder能够自动化大部分工作,但开发者依然可以自定义模板,对生成的代码进行微调,以满足特定项目的需求。这种灵活性确保了生成的代码既高效又符合项目风格。 6. **提高开发效率**: 使用CoolCoder,...

    MediaCoder

    MediaCoder是一款功能强大的多媒体转换工具,它支持广泛的音频和视频编码格式,使用户能够轻松地在不同设备之间转换媒体文件。这款软件适用于个人用户、专业音频和视频制作人员,以及那些希望在各种设备上享受多媒体...

    php coder编辑器

    PHPCoder用于快速开发和调试PHP应用程序,它很容易扩展和定制,完全能够符合开发者的个性要求.PHPCoder是一个非常实用的,功能强大的编程环境,而且它是免费的!

    matlab coder基本函数教程

    ### MATLAB Coder 基本函数教程 #### MATLAB Coder 概述 MATLAB Coder 是一款能够将 MATLAB 代码转换成独立的 C 或 C++ 代码的强大工具。这一过程对于那些希望在非 MATLAB 环境下部署 MATLAB 代码的应用开发者来说...

    HDL-Coder详细教程

    ### HDL-Coder详细教程知识点概述 #### 一、生成HDL代码前的准备工作 在开始从Simulink模型生成HDL代码之前,需要完成一系列的准备工作,确保模型能够顺利生成高质量的代码。 ##### 1.1 使用`hdlsetup`进行模型...

    MediaCoder.5755专业破解版

    MediaCoder行业版一款针对VOD及KTV视频点播行业开发的,用于转换和处理带有多音轨内容的视频节目的软件。它具备业界领先的视频编码引擎,在高性能转码的同时保持高画质,并通过丰富的视频滤镜增强画面视觉效果。作为...

    MediaCoder使用说明文档

    MediaCoder使用说明文档, mediaCoder usermanual,

    MatlabCoder使用-Matlab Coder的基本使用.pdf

    Matlab Coder是Mathworks公司推出的一款用于将Matlab代码转换成高效C代码的工具。从2004年开始,Matlab陆续在Simulink中添加了Embeded Matlab Function模块,2007年在Real-Time Workshop中引入了emlc函数(现在的...

    Embedded Coder.rar

    texasinstrumentsc2000.mlpkginstall 支持TI的C2000系列工具包,要求MATLAB R2017a及其以上版本。 安装方法:打开matlab,调整路径到mlpkginstall文件所在目录;在current folder窗口里双击mlpkginstall文件即可开始...

    MediaCoder64位专业破解版

    MediaCoder-Premium-x64 MediaCoder是最早开始使用GPU进行视频编码加速的影音转码软件之一。通过将原本完全依赖CPU的计算工作转移到GPU上进行,H.264和H.265编码所需的时间被大幅缩短。

Global site tag (gtag.js) - Google Analytics