HttpSession 入门
1. HttpSession 概述
- 位于 javax.servlet.http 包;
- HttpSession 是由 JavaWeb 提供的功能, 用来会话跟踪的类, session 是服务器端对象, 保存在服务器端!!!
- HttpSession 底层依赖 Cookie, 或是 URL 重写!
2. HttpSession 的作用
- 会话范围: 从某个用户首次访问服务器开始, 到该用户关闭浏览器结束!
- 会话: 一个用户对服务器的多次连贯性请求! 所谓连贯性请求, 就是该用户多次请求中间没有关闭浏览器!
- 服务器会为每个用户创建一个 Session 对象, session 就好比用户在服务器端的账户, 它们被服务器保存到
一个 Map 中, 这个 Map 被称之为 session 的缓存.
- Servlet 中得到 session 对象:HttpSession session = request.getSession();
- JSP 中得到 session 对象: session 是 JSP 内置对象之一, 不用创建就可以直接使用! - 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 对象.
如果创建了新的 session, 浏览器会得到一个包含了 sessionId 的 Cookie, 这个 Cookie 的生命为 -1,
即只在浏览器内存中存在. 浏览器关闭后,该 Cookie 会被删除.服务器并不会在访问页面时,马上给你创建 session 对象, 只有在第一次获取 session 对象时, 才会调用
request.getSession()
方法创建 session 对象.- 访问 ".jsp" 文件会自动调用
request.getSession();
方法; - 访问 Servlet 页面, 需要人工写入
request.getSession();
方法.
- 访问 ".jsp" 文件会自动调用
多次请求: 如果第一次请求创建了 session 对象. 第二次请求, 服务器端再次执行
request.getSession()
方
法,服务器端可以通过 Cookie 中的 JSESSIONID 找到第一次请求创建的 session 对象. 所以与上一次请求使
用的是同一个 session 对象.方法比较:
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 参数. 否则, 不会重写.
- 该方法会对 url 进行智能的重写, 当请求中没有归还 sessionId 这个 cookie, 那么该方法会重写 url,
参考资料:
HttpSession 入门的更多相关文章
- day11(jsp入门&Cookie&HttpSession&一次性图片校验码)
day11 JSP入门 1 JSP概述 1.1 什么是JSP JSP(Java Server Pages)是JavaWeb服务器端的动态资源.它与html页面的作用是相同的,显示数据和获取数据. ...
- SpringMVC 入门
MVC 简介 1.MVC 是一种架构模式 程序分层,分工合作,既相互独立,又协同工作,分为三层:模型层.视图层和控制层 2.MVC 是一种思考方式 View:视图层,为用户提供UI,重点关注数据的呈现 ...
- Hibernate(二)__简单实例入门
首先我们进一步理解什么是对象关系映射模型? 它将对数据库中数据的处理转化为对对象的处理.如下图所示: 入门简单实例: hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中 ...
- Struts2 入门
一.Struts2入门案例 ①引入jar包 ②在src下创建struts.xml配置文件 <?xml version="1.0" encoding="UTF-8&q ...
- Apache Shiro系列三,概述 —— 10分钟入门
一.介绍 看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro.以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定. 二.概述 关于Shiro的废话就不多说了 ...
- Tomcat基本入门知识及发布,虚拟访问及启动碰到的错误,虚拟目录,虚拟路径,各种Tomcat的配置
Tomcat容器入门介绍 转自javaresearch.com由timgball 整理 Tomcat是一个免费的开源Web服务器,最新版本是5.5.1,支持Servlet2.4,JSP2.0,非常适合 ...
- Struts2入门2 Struts2深入
Struts2入门2 Struts2深入 链接: http://pan.baidu.com/s/1rdCDh 密码: sm5h 前言: 前面学习那一节,搞得我是在是太痛苦了.因为在Web项目中确实不知 ...
- MyBatis入门学习
所需要jar包:mybatis-3.x.x.jar .如果需要和spring整合,还需要加入相关的包 1:看项目目录 红颜色不要关心 2:按照步骤: 1:加入jar包 2:创建数据源(configur ...
- Jsp,EL表达式的入门
Jsp,EL表达式的入门 *Servlet/JSP 是两种动态的WEB资源的两种技术 使用Servlet生成HTML的页面是可以的 response.getWriter("<form ...
随机推荐
- linux Apache CGI 安装配置
Apache 中的提交了一种利用扩展应用程序执行动态网页的机制. 称为Common Gateway Interface (通用网关接口)简称CGI. 本文假定已安装好linux(本文的linux版本为 ...
- mysql 求季度产量平均值
表名:product 表结构: 表数据: 如果使用日期查询的话:sql: SELECT QUARTER(create_time) AS '季度',AVG(seller) AS '平均值' FROM p ...
- PHP学习笔记(12)分页技术
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ext,exrReturn新增,修改删除等用
package cn.edu.hbcf.common.vo; /** * Ext Ajax 返回对象 * * @author * @date 2012-02-21 19:30:00 * */ publ ...
- Github上Fork代码,及源码修改
iOS开发中经常遇到这种情况,你使用的第三方库不能完全满足自己项目需要,只能修改源码来解决. 我们以前的解决办法是,添加到项目中直接修改源码.这样就有一个问题,不能和源库同步,当作者更新后你不能(po ...
- libubox-runqueue
参考:libubox [4] - uloop runqueue ustream 任务队列是通过uloop定时器实现,把定时器超时时间设置为1,通过uloop事件循环来处理定时器就会处理任务队列中的ta ...
- 通过某个进程号显示该进行打开的文件 lsof -p 1 11. 列出多个进程号对应的文件信息 lsof -p 123,456,789 5. 列出某个用户打开的文件信息 lsof -u username
linux命令 — lsof 查看进程打开那些文件 或者 查看文件给那个进程使用 lsof命令是什么? 可以列出被进程所打开的文件的信息.被打开的文件可以是 1.普通的文件,2.目录 3.网络文件系 ...
- 第二百三十节,jQuery EasyUI,后台管理界面---后台管理
jQuery EasyUI,后台管理界面---后台管理 一,admin.php,后台管理界面 <?php session_start(); if (!isset($_SESSION['admin ...
- Java中static的使用
static 使用之静态变量: 大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 static 大 ...
- jquery添加!important样式
$("span.colorFlag").parents("th").css("cssText","background-color ...