1. HttpSession 概述

  • 位于 javax.servlet.http 包;
  • HttpSession 是由 JavaWeb 提供的功能, 用来会话跟踪的类, session 是服务器端对象, 保存在服务器端!!!
  • HttpSession 底层依赖 Cookie, 或是 URL 重写!

2. HttpSession 的作用

  1. 会话范围: 从某个用户首次访问服务器开始, 到该用户关闭浏览器结束!

    • 会话: 一个用户对服务器的多次连贯性请求! 所谓连贯性请求, 就是该用户多次请求中间没有关闭浏览器!
  2. 服务器会为每个用户创建一个 Session 对象, session 就好比用户在服务器端的账户, 它们被服务器保存到

    一个 Map 中, 这个 Map 被称之为 session 的缓存.

    - Servlet 中得到 session 对象: HttpSession session = request.getSession();

    - JSP 中得到 session 对象: session 是 JSP 内置对象之一, 不用创建就可以直接使用!
  3. session 域相关方法:
    • void setAttribute(String name, Object value);
    • Object getAttribute(String name); : 返回值为 Object 类型, 需要强转!
    • void removeAttribute(String name);

// 示例: 保存用户登录信息
/*
* 相关页面和 Servlet
* login.jsp: 登录页面
* succ1.jsp: 只有登录成功才能访问的页面
* LoginServlet: 校验用户是否登录成功
*
* 各页面和 Servlet 内容:
* login.jsp: 提供登录表单, 将表单请求数据提供给 LoginServlet, 如果登录失败,需要显示错误信息
* LoginServlet: 获取请求参数, 校验用户是否登录成功
* 失败: 保存错误信息到 request 域, 转发到 login.jsp( login.jsp 显示 request 域中的错误信息)
* 成功: 保存用户信息到 session 域中, 重定向到 succ1.jsp 页面, 显示 session 域中的用户信息
*
* succ1.jsp: 从 session 域获取用户信息, 如果不存在, 显示"您还没有登录", 存在则显示用户信息
* succ2.jsp: 从 session 域获取用户信息, 如果不存在, 显示"您还没有登录", 存在则显示用户信息
*
* 只要用户没有关闭浏览器, session 就一直存在, 那么保存在 session 中的用户信息也就一直存在! 那么用户访问
* succ1 就会成功!
*
* 附加项(浏览器保存用户信息):
* 把用户名保存到 cookie 中, 发送给客户端浏览器
* 当再次打开 login.jsp 时, login.jsp 会读取 request 中的 cookie, 把它显示到用户名文本框中.
*/ // login.jsp <head>
// 换一张的函数
<script type="text/javascript">
function _change(){
// 获取 img 节点
var imgEle = document.getElementById("img");
// 对该节点的 src 属性重新赋值
imgEle.src = "/day11_1/VerifyCodeServlet?a="+new Date().getTime();
}
</script>
</head> <body>
// 获取 cookie 中的信息
<%
// 定义变量, 并赋值为空
String uname = "";
Cookie[] cks = request.getCookies();
// 如果有 cookie 存在
if(cks != null){
// 遍历数组
for(Cookie ck:cks){
if("uname".equals(ck.getName())){
uname = ck.getValue();
}
}
}
%> // 显示错误信息
<%
String message = "";
String msg = (String)request.getAttribute("msg");
if(msg != null){
message = msg;
}
%> <h1>登录</h1>
// 显示错误信息
<font color="red"><b><%=message %></b></font> // 正常表单
<form action="" method="POST">
// 注意: <%=uname %> 需要使用引号引起来
// value 是 cookie 中的用户名, 显示到文本框中
用户名:<input type="text" name="username" value="<%=uname %>"/><br/>
密 码:<input type="password" name="psw"/><br/>
验证码:<input type="text" name="verifyCode" size="3"/>
<img id="img" src="/day11_1/VerifyCodeServlet" />
<a href="javascript:_change()">换一张</a><br/>
<input type="submit" value="提交"/>
</form>
</body> // LoginServlet
public void doPost(HttpServletRequest request, HttpServletResponse response){
//首先处理 POST 编码问题
request.setCharacterEncoding("uft-8"); // 获取 request 请求表单中的数据, 不是 request 域
String name = request.getParameter("username"); // 获取 session 域中验证码数据
String sessionCode = request.getSession().getAttribute("session_vcode");
// 获取 request 请求中的验证码
String paramCode = request.getParamter("verifyCode");
// 比较两者
if(!paramCode.equalsIgnoreCase(sessionCode)){
request.setAttribute("msg","您填写的验证码有误!");
//转发
request.getRequestDispatcher("login.jsp").forward(request,response);
return;
} // 判断,只要不是 "itcast",就能登录成功, 重定向至 succ1.jsp
// 否则,保存错误信息到 request域中, 转发至 login.jsp
if(!"itcast".equalsIgnoreCase(name)){
// 附加项: 浏览器保存用户信息, 方便第二次登录
Cookie ck = new Cookie("uname",name);
ck.setMaxAge(60*60*24); // 最长在浏览器保存 1 天
response.addCookie(ck); // 获取 session 域
HttpSession session = request.getSession();
// 保存用户名到session域
session.setAttribute("username",name);
// 重定向到 succ1.jsp, 路径中需要加入项目名
response.sendRedirect("/day11_1/succ1.jsp");
} else {
// 保存错误信息到 request 域
request.setAttribute("msg","用户名或密码错误!");
// 转发至login.jsp
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
} // VerifyCodeServlet
public class VerifyCodeServlet extends HttpServlet{
pubilc void doGet{
VerifyCode vc = new VerifyCode();
BufferedImage bi = vc.getImage();
// 将图片中的文本保存到 session 域中
request.getSession().setAttribute("session_vcode",vc.getText());
// 将图片显示在 login.jsp 页面
VerifyCode.output(bi,response.getOutputStream());
}
} // succ1.jsp
<body>
// 如果用户通过输入地址来访问该页面, 需要判断 session 中的用户名
<%
String name = (String)session.getAttribute("username");
if(name == null){
// 保存错误信息
request.setAttribute("msg","您还没有登录!"); // 转发到 login.jsp, 留头不留体
request.getRequestDispatcher("/login.jsp").forward(request,response);
// 结束程序, 下面的内容不会输出
return;
}
%>
<h1>Succ1</h1>
欢迎<%=name %>光临本网站!!
</body>

3. HttpSession 原理

获取 Cookie 中的 JSESSIONID, 使用 request.getSession() 方法

  • 如果 sessionId 不存在, 服务器创建 session 对象, 把 session 保存起来, 把新创建的 sessionID 保存到 Cookie 中;
  • 如果 sessionId 存在, 通过 sessionId 查找 session 对象, 如果没有找到, 创建 session, 把 session 保存

    起来, 把新创建的 sessionId 保存到 Cookie 中;
  • 如果 sessionId 存在, 通过 sessionId 查找到了 session 对象, 那么就不会创建 session 对象了.
  • 返回 session 对象

备注: session 对象存储在服务器端的 Map 集合中, 键为:sessionId, 值为: session 对象.

  1. 如果创建了新的 session, 浏览器会得到一个包含了 sessionId 的 Cookie, 这个 Cookie 的生命为 -1,

    即只在浏览器内存中存在. 浏览器关闭后,该 Cookie 会被删除.

  2. 服务器并不会在访问页面时,马上给你创建 session 对象, 只有在第一次获取 session 对象时, 才会调用

    request.getSession()方法创建 session 对象.

    • 访问 ".jsp" 文件会自动调用 request.getSession(); 方法;
    • 访问 Servlet 页面, 需要人工写入 request.getSession(); 方法.
  3. 多次请求: 如果第一次请求创建了 session 对象. 第二次请求, 服务器端再次执行 request.getSession()

    法,服务器端可以通过 Cookie 中的 JSESSIONID 找到第一次请求创建的 session 对象. 所以与上一次请求使

    用的是同一个 session 对象.

  4. 方法比较:

    • request.getSession(true); : 与 request.getSession(); 效果相同;
    • request.getSession(false);: 如果 session 缓存中,不存在 session,返回 null,而不会创建 session

      对象. 如果 cookie 不存在, 也不会创建 session 对象.

4. HttpSession 其他方法

  • String getId(); : 获取 sessionId(32 位长字符串);
  • int getMaxInactiveInterval(); : 获取 session 对象的最大不活动时间(秒), 默认为 30 分钟;

    当 session 对象在30分钟内没有使用, 那么会被 Tomcat 从 session 池中移除.
  • void invalidate(); : 让 session 失效!
  • boolean isNew(); : 查看 session 对象是否为新
// 获取 UUID, 也就是 sessionId
// J2SE 中的 java.util 中有 UUID 类
UUID uuid = UUID.randomUUID();
String str = uuid.toString();
str = str.replace("-","");
str = str.toUpperCase();

5. web.xml 中配置 session 的最大不活动时间(分钟)

<session-config>
<session-timeout>30</session-timeout>
</session-config>

6. URL 重写 (理解)

  • session 依赖 Cookie, 目的是让客户端发送请求时,归还 sessionId, 这样才可能找到对应的 session 对象;
  • 如果客户端禁用了 Cookie, 那么就无法得到 sessionId, 那么 session 也就没法使用了!
  • 这时, 可以使用 URL 重写来替代 Cookie
    • 让网站的所有超链接, 和表单中都添加一个特殊的请求参数, 即 sessionId;
    • 这样服务器可以通过获取请求参数得到 sessionId, 从而找到 session 对象;
  • response.encodeURL(String url);
    • 该方法会对 url 进行智能的重写, 当请求中没有归还 sessionId 这个 cookie, 那么该方法会重写 url,

      在指定的 url 后添加 JESSIONID 参数. 否则, 不会重写.

参考资料:

HttpSession 入门的更多相关文章

  1. day11(jsp入门&Cookie&HttpSession&一次性图片校验码)

    day11 JSP入门   1 JSP概述 1.1 什么是JSP JSP(Java Server Pages)是JavaWeb服务器端的动态资源.它与html页面的作用是相同的,显示数据和获取数据. ...

  2. SpringMVC 入门

    MVC 简介 1.MVC 是一种架构模式 程序分层,分工合作,既相互独立,又协同工作,分为三层:模型层.视图层和控制层 2.MVC 是一种思考方式 View:视图层,为用户提供UI,重点关注数据的呈现 ...

  3. Hibernate(二)__简单实例入门

    首先我们进一步理解什么是对象关系映射模型? 它将对数据库中数据的处理转化为对对象的处理.如下图所示: 入门简单实例: hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中 ...

  4. Struts2 入门

    一.Struts2入门案例 ①引入jar包 ②在src下创建struts.xml配置文件 <?xml version="1.0" encoding="UTF-8&q ...

  5. Apache Shiro系列三,概述 —— 10分钟入门

     一.介绍 看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro.以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定. 二.概述 关于Shiro的废话就不多说了 ...

  6. Tomcat基本入门知识及发布,虚拟访问及启动碰到的错误,虚拟目录,虚拟路径,各种Tomcat的配置

    Tomcat容器入门介绍 转自javaresearch.com由timgball 整理 Tomcat是一个免费的开源Web服务器,最新版本是5.5.1,支持Servlet2.4,JSP2.0,非常适合 ...

  7. Struts2入门2 Struts2深入

    Struts2入门2 Struts2深入 链接: http://pan.baidu.com/s/1rdCDh 密码: sm5h 前言: 前面学习那一节,搞得我是在是太痛苦了.因为在Web项目中确实不知 ...

  8. MyBatis入门学习

    所需要jar包:mybatis-3.x.x.jar .如果需要和spring整合,还需要加入相关的包 1:看项目目录 红颜色不要关心 2:按照步骤: 1:加入jar包 2:创建数据源(configur ...

  9. Jsp,EL表达式的入门

    Jsp,EL表达式的入门 *Servlet/JSP 是两种动态的WEB资源的两种技术 使用Servlet生成HTML的页面是可以的 response.getWriter("<form ...

随机推荐

  1. vivado设计三:一步一步生成自己的自定义IP核

    开发环境:xp  vivado2013.4 基于AXI-Lite的用户自定义IP核设计 这里以用户自定义led_ip为例: 1.建立工程 和设计一过程一样,见vivado设计一http://blog. ...

  2. 413. Reverse Integer【easy】

    Reverse digits of an integer. Returns 0 when the reversed integer overflows (signed 32-bit integer). ...

  3. poj 1636 Prison rearrangement

    Prison rearrangement   Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 2158   Accepted: ...

  4. cocoa pods 升级遇到的问题

    1. cocoa pods 升级遇到的问题 运行 sudo gem update --system 报错 Updating rubygems-update ERROR: While executing ...

  5. 0052 Spring MVC入门--环境搭建--第一个入门示例

    Spring MVC是什么 Spring是一个框架,包括了MVC.IoC.AOP等等组件 MVC是一种思想,并非Spring框架独有,全称是Model.View.Controller,即模型.视图.控 ...

  6. Highcharts 图表js框架

    纯js图表框架 ,图表传入Json数据 设置等等   , 如没特定要求可以考虑使用   优点 : 减轻服务器脚本运行负重  ,纯js执行,特效   缺点: 已知兼容性不高 帮助地址: http://w ...

  7. Effective C++:条款39:明智而审慎地使用private继承

    (一) (1)private继承意味着"依据某物实现出".仅仅有实现部分被继承.接口部分应略去: (2)它仅仅在软件"实现"层面上有意义,在软件"设计 ...

  8. The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Cha

    The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Cha ...

  9. Mac OSX使用隐藏文件夹

    直接修改文件夹名字,前面加个"." 小圆点就隐藏了,下去进入可以在finder图标右键点菜单“前往文件夹...",输入你文件夹的路径即可

  10. lstrcpyn

    看代码时遇到的一些不会用的函数,记录下来. 1. lstrcpyn LPTSTR lstrcpyn( __out LPTSTR lpString1, __in LPCTSTR lpString2, _ ...