⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsp_servlet_conversation.htm

📁 写给JSP初级程序员的书
💻 HTM
📖 第 1 页 / 共 2 页
字号:
              <br>
              validSessionIdFound是一个标记,用于指示会话标识符是否合法。validSessionIdFound的初始值是false。 
              <br>
              boolean validSessionIdFound = false; <br>
              long类型的now变量包含请求出现时的服务器时间。该变量用于确定用户会话的合法性。 <br>
              long now = System.currentTimeMillis(); <br>
              如果找到了会话标识符,则getSessionID方法检查它的合法性。检查过程如下: <br>
              · 一个合法的会话标识符必须有对应的同名文本文件。 <br>
              · 文件的最后修改时间加上timeOut应该大于当前时间。 <br>
              · 如果存在与会话对应的文本文件,但文件已经过期,则原来的文件被删除。 <br>
              · 把合法会话标识符所对应文本文件的最后修改日期改为now。 <br>
              这些任务主要借助File对象完成,创建File对象的参数就是会话文本文件的路径: <br>
              if (sessionId!=null) {File f = new File(path + sessionId);if (f.exists()) 
              { if (f.lastModified() + timeOut &gt; now) { // 会话合法// 使用setLastModified时,如果文件已经被其他程序锁定,// 
              程序不会产生任何异常,但文件数据不会改变f.setLastModified(now);validSessionIdFound = 
              true; } else { // 会话已经过期 // 删除文件f.delete(); }} // end if (f.exists) 
              } // end if (sessionId!=null) <br>
              如果不存在合法的会话标识符,则getSessionID方法生成一个会话标识符以及相应的文本文件: <br>
              if (!validSessionIdFound) { sessionId = Long.toString(now); // 创建文件 
              File f = new File(path + sessionId); try {f.createNewFile(); } catch 
              (IOException ioe) {}} // end of if !validSessionIdFound <br>
              程序保证文件名字随机性的方法非常简单:把当前的系统时间直接转换成会话标识符。对于那些涉及敏感数据的应用,我们应该考虑运用更安全的随机数生成器来生成会话标识符。 
              <br>
              综上所述,getSessionID并不总是返回新的合法会话标识符:它返回的标识符可能与传递给它的标识符相同,也可能是新创建的会话标识符。 
              <br>
              为了保证JSP页面拥有合法的会话标识符以便调用setValue、getValue方法,每个JSP页面都必须在开头位置调用getSesstionID方法。 
            </p>
            <p><br>
              4.2 setValue方法 <br>
              setValue方法保存value字符串以及与它关联的字符串名字。这种“名字-值”对很容易使人想起Dictionary对象。setValue方法要求在第一个参数中提供合法的会话标识符,它假定在自己被调用之前getSessionID方法已经执行,经过检验的合法会话标识符必然存在,因此它不再对传入的会话标识符进行合法性检验。 
              <br>
              setValue方法按如下规则保存名字-值对: <br>
              · 如果与value值关联的name以前还没有保存过,则新的名字-值对加入到文本文件的末尾。 <br>
              · 如果value字符串关联的name值以前已经保存过,则原来保存的值被新的value值替换。 <br>
              setValue方法按照如下格式保存名字-值对,注意“名字”是大小写敏感的: <br>
              name-1 value-1name-2 value-2name-3 value-3...name-n value-n <br>
              setValue方法的声明如下: <br>
              public void setValue(String sessionId, String name, String value) 
              <br>
              setValue方法首先寻找与当前会话对应的文本文件。如果不能找到文本文件,则setValue方法不做任何事情直接返回。如果找到了会话文本文件,setValue方法读取文本文件的各个行,然后比较读入的行与name:如果读入的文本行开头与name一样,则说明该名字已经保存,setValue方法将替换该行后面的值;如果name不能与读入的文本行匹配,则这行文本被直接复制到一个临时文件。 
              <br>
              这部分功能的实现代码如下: <br>
              try { FileReader fr = new FileReader(path + sessionId); BufferedReader 
              br = new BufferedReader(fr); FileWriter fw = new FileWriter(path 
              + sessionId + &quot;.tmp&quot;); BufferedWriter bw = new BufferedWriter(fw); 
              String s; while ((s = br.readLine()) != null)if (!s.startsWith(name 
              + &quot; &quot;)) { bw.write(s); bw.newLine();} bw.write(name + 
              &quot; &quot; + value); bw.newLine(); bw.close(); br.close(); fw.close(); 
              bw.close(); . . .}catch (FileNotFoundException e) {}catch (IOException 
              e) { System.out.println(e.toString());} <br>
              原来文本文件中的所有行复制到临时文件之后,setValue方法删除原来的文本文件,然后把临时文件改成会话文本文件的名字: <br>
              File f = new File(path + sessionId + &quot;.tmp&quot;);File dest 
              = new File(path + sessionId);dest.delete();f.renameTo(dest); </p>
            <p><br>
              4.3 getValue方法 <br>
              getValue方法用于提取原来保存在伪会话中的数据。正如setValue方法,getValue方法也要求传入一个合法的会话标识符,而且getValue方法不再对传入的会话标识符进行合法性检查。getValue方法的第二个参数是待提取数据的name,返回值是与指定name关联的value。 
              <br>
              getValue方法的声明如下: <br>
              public String getValue(String sessionId, String name) <br>
              getValue方法的基本执行过程如下:首先找到会话文本文件,然后按行读入直至找到与name匹配的文本行;找到匹配的文本行之后,getValue方法返回该行保存的value;如果不能找到,getValue方法返回null。 
            </p>
            <p><br>
              4.4 deleteAllInvalidSessions方法 <br>
              deleteAllInvalidSessions方法删除那些与已经过期的会话关联的文本文件。由于调用getSessionID方法时过期的会话文本文件会被删除,deleteAllInvalidSessions方法并不是关键的方法。什么时候调用这个方法由应用自己决定。例如,我们可以编写一个专用的后台程序,由这个程序每天一次清除所有过期的文本文件。最简单的办法是在JSP文件末尾调用deleteAllInvalidSessions方法,但如果网站比较繁忙,重复地调用deleteAllInvalidSessions方法将降低整个网站的响应能力。一种明智的做法是:编写一个在访问量较少的时候自动进行清理的后台程序。 
              <br>
              deleteAllInvalidSessions方法的声明如下: <br>
              public void deleteAllInvalidSessions() <br>
              它首先把所有会话文本文件的名字读入files字符串数组: <br>
              File dir = new File(path); String[] files = dir.list(); <br>
              deleteAllInvalidSessions方法比较文本文件的最后修改时间(加上超时时间)和系统当前时间,确定会话是否过期。long类型的变量now用于保存系统的当前时间。 
              <br>
              long now = System.currentTimeMillis(); <br>
              接下来,deleteAllInvalidSessions方法通过循环访问files数组,依次检查每个文件的lastModified属性。所有与过期会话关联的文件都将被删除: 
              <br>
              for (int i=0; i&lt;files.length; i++) { File f = new File(path + 
              files[i]); if (f.lastModified() + timeOut &gt; now) f.delete(); 
              // 删除过期的会话文本文件} </p>
            <p><br>
              五、应用实例 </p>
            <p><br>
              编译好PseudoSessionBean这个JavaBean之后,我们就可以利用伪会话管理机制来管理Web应用的会话状态信息了。由于不必再使用服务器的会话管理机制,我们可以在page指令中把session属性设置为false关闭默认的JSP/Servlet会话管理功能。 
              <br>
              &lt;%@ page session=&quot;false&quot; %&gt; </p>
            <p>然后,我们用JSP的&lt;jsp:useBean&gt;标记告诉JSP容器程序要使用PseudoSessionBean: <br>
              &lt;jsp:useBean id=&quot;PseudoSessionId&quot; scope=&quot;application&quot; 
              class=&quot;pseudosession.PseudoSessionBean&quot; /&gt; </p>
            <p>在上面这个&lt;jsp:useBean&gt;标记中,class属性值是“包.类名字”形式。当然,对于不同的包名字,class属性的值应该作相应的修改。注意Bean的scope属性是“application”,这是因为我们要在应用的所有页面中使用这个Bean。在这个应用中,把Bean的scope属性设置为“application”具有最好的效率,因为我们只需创建Bean对象一次就可以了。另外,正如前面所提到的,getSessionID方法必须在所有其他代码之前调用。 
              <br>
              &lt;% String sessionId = PseudoSessionId.getSessionID(request);%&gt; 
              <br>
              为了说明PseudoSessionBean的应用,下面我们来看两个JSP页面,它们是index.jsp和secondPage.jsp。index.jsp页面在伪会话变量中保存用户的名字,而secondPage.jsp则提取这个用户名字。 
            </p>
            <p>index.jsp页面的代码如下: <br>
              &lt;%@ page session=&quot;false&quot; contentType=&quot;text/html;charset=gb2312&quot; 
              %&gt;&lt;jsp:useBean id=&quot;PseudoSessionId&quot; scope=&quot;application&quot; 
              class=&quot;pseudosession.PseudoSessionBean&quot; /&gt;&lt;% String 
              sessionId = PseudoSessionId.getSessionID(request);%&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;伪会话&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;伪会话管理机制&lt;/h1&gt;<br>
              &lt;% String userName = &quot;bulbul&quot;; PseudoSessionId.setValue(sessionId, 
              &quot;userName&quot;, userName);%&gt;&lt;a href=secondPage.jsp?sessionId=&lt;%=sessionId%&gt;&gt;点击此处&lt;/a&gt;<br>
              &lt;form method=&quot;post&quot; action=anotherPage.jsp?sessionId=&lt;%=sessionId%&gt;&gt;<br>
              输入数据:&lt;input type=&quot;text&quot; name=&quot;sample&quot;&gt;<br>
              &lt;input type=&quot;submit&quot; name=&quot;Submit&quot; value=&quot;Submit&quot;&gt;&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;&lt;% 
              PseudoSessionId.deleteAllInvalidSessions();%&gt; </p>
            <p>注意,包括&lt;form&gt;标记的action属性在内,所有的超级链接都已经改写,现在都包含了会话标识符。另外也请注意页面的最后调用了deleteAllInvalidSessions方法。 
              <br>
              secondPage.jsp页面只简单地返回以前保存的用户名字。 <br>
              &lt;%@ contentType=&quot;text/html;charset=gb2312&quot; page session=&quot;false&quot; 
              %&gt;&lt;jsp:useBean id=&quot;PseudoSessionId&quot; scope=&quot;application&quot; 
              class=&quot;pseudosession.PseudoSessionBean&quot; /&gt;&lt;% String 
              sessionId = PseudoSessionId.getSessionID(request);%&gt;&lt;html&gt;&lt;head&gt;&lt;title&gt;第2个页面&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;% 
              String userName = PseudoSessionId.getValue(sessionId, &quot;userName&quot;); 
              out.println(&quot;用户名字是 &quot; + userName);%&gt;&lt;/body&gt;&lt;/html&gt; 
            </p>
            <p></p>
            <!-- #EndEditable --></td>
          <td width="20">&nbsp;</td>
        </tr>
        <tr> 
          <td width="20" height="11">&nbsp;</td>
          <td width="541" height="11"><!-- #BeginEditable "7" --><!-- #EndEditable --></td>
          <td width="101" height="11"> 
            
          </td>
          <td width="20" height="11">&nbsp;</td>
        </tr>
      </table><div align="center"> <br>
      </div>
      
    </td>
  </tr>
</table>
<div align="center"> 
  
  <br>
</div>
</body>
<!-- #EndTemplate -->
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -