Session
-
会话技术
浏览器和服务器之间为了实现某一个功能,产生了多次的请求和响应,从第一次请求开始到最后一个请求结束,这期间产生的这些请求和响应加在一起就称之为浏览器和服务器之间产生了一次会话。
会话最重要的问题就是如何存储会话产生的数据。 -
Session概述
Session是javaweb提供的解决会话数据存储相关的技术。
Session是服务器端技术,将会话产生的数据存储在服务器端。
Session技术在服务端为每个客户端创建各自的session对象,用来存储与该客户端会话产生的数据。
每个客户端都使用各自对应的session对象存储会话数据,不会产生混乱。
- Session是一个域对象
Session是一个域对象
Session域用来在一个会话范围内共享数据
a. 操作API
i. 创建获取session
HttpSession session = request.getSession()
如果当前会话没有对应的session,这个方法创建Session并返回Session
如果当前会话有对应的session,这个方法直接返回对应session
ii. 销毁session
session.invalidate()
此方法可以立即销毁session
iii. 操作session
b. 特点
i. 生命周期
-
一种活法:
第一次调用request.getSession()创建session -
三种死法:
超时:
session连续超过30分钟没人使用,则超时销毁。
可以在web.xml修改session超时时间
自杀:
手动调用session.invalidate()可以立即杀死session
意外身亡:
当服务器非正常关闭时,随着应用的销毁session被销毁
如果服务器是正常关闭,则服务器会将还存活的session序列化存储到tomcat/work目录下,这个过程叫做sessoin的钝化。
等服务器下次启动时,会将tomcat/work目录下存储的session恢复回内存,这个过程叫session的活化。
ii. 作用范围
在一个会话范围内生效
iii. 主要功能
在一个会话范围共享数据
- Session案例:EasyMall-注册时验证码的实现
a. 发送验证码时将验证码的值存储到session中
b. 校验验证码时从session中取出验证码和用户提交的验证码做比较
- Session案例:EasyMall-用户登录
根据用户提交的用户名密码,查询数据,错误就提示,正确将用户信息封装到bean中存入session作为登录标记
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.解决乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//1.获取用户提交的用户名密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//2.查询数据库校验用户名密码
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
//--注册数据库驱动
//--获取数据库连接
conn = JDBCUtils.getConn();
//--获取传输器
ps = conn.prepareStatement("select * from user where username = ? and password = ?");
ps.setString(1,username);
ps.setString(2,password);
//--传输sql执行获取结果集
rs = ps.executeQuery();
//--获取结果数据
if(rs.next()){
//3.正确就登录,重定向回主页
//--将查询到的用户信息转为user对象
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setNickname(rs.getString("nickname"));
user.setEmail(rs.getString("email"));
//--获取session
HttpSession session = request.getSession();
//--将user对象存储到session中作为登录标记
session.setAttribute("user",user);
//--重定向回主页
response.sendRedirect(request.getContextPath()+"/index.jsp");
return;
}else{
//3.不正确,转发回到登录页面提示错误消息
request.setAttribute("msg","用户名密码不正确!");
request.getRequestDispatcher("/login.jsp").forward(request,response);
return;
}
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}finally {
//--关闭资源
JDBCUtils.close(conn,ps,rs);
}
}
在主页中,根据是否存在登录标记,提示不同信息
<%
if(session.getAttribute("user")==null){
%>
<a href="<%=request.getContextPath()%>/login.jsp">登录</a>
|
<a href="<%=request.getContextPath()%>/regist.jsp">注册</a>
<%
}else{
%>
欢迎回来!<%=((User)session.getAttribute("user")).getUsername()%>!
<a href="<%=request.getContextPath()%>/LogoutServlet">[登出]</a>
<%
}
%>
- Session案例:EasyMall-用户登出
当用户进行登出操作时,从session中移除登录标记,或直接杀死session,即可登出
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从session中移除登录标记
//HttpSession session = request.getSession();
//session.removeAttribute("user");
//杀死session
HttpSession session = request.getSession();
session.invalidate();
//重定向回主页
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
- Session原理
Session是基于一个名为JSESSIONID特殊的Cookie工作的
服务器中每一个session都会有一个独一无二的session id
当为当前客户端创建session时,会在响应中通过名为JSESSIONID的Cookie将当前session的id发送给浏览器
浏览器之后每次访问都会带着这个JSESSIONID cookie,服务器解析JSESSIONID cookie,得到session的id 找到对应session为当前客户机服务。
Cookie
- Cookie概述
Cookie是javaweb提供的解决会话数据存储相关的技术。
Cookie是客户端端技术,将会话产生的数据存储在客户端。
Cookie基于set-Cookie响应头和Cookie请求头工作。
当服务器需要保存会话相关数据时,通过发送set-Cookie响应头命令浏览器保存指定会话数据。浏览器收到后会将数据保存在浏览器中。
之后当再次去访问服务器时,浏览器通过Cookie请求头将保存的数据再此带回给服务器,服务器获取数据来使用。
每个浏览器各自保存各自的Cookie信息,保证会话数据不会混乱。
- 创建Cookie
a. 构造方法
b. 设置MaxAge
如果设置MaxAge,则
设置MaxAge可以指定浏览器将Cookie保存多久
一旦设置此属性,cookie会被浏览器以临时文件的形式保存指定时长
在超时之前一直存在,即使多次开关浏览器cookie也不会消失
经过指定时长,临时文件超时,浏览器自动清除临时文件,cookie被删除
如果不设置MaxAge,则
cookie保存在浏览器的内存中
浏览器页面什么时候关闭cookie什么时候销毁
这样的cookie也被称为会话级别的cookie
c. 设置Path
可以通过设置Path指定浏览器在访问哪个路径及其子孙路径时带回此cookie
如果不设置,cookie默认的Path为当前路径的父路径
http://localhost/JavaWebDay11_04_Cookie/MyServlet01
-->
http://localhost/JavaWebDay11_04_Cookie
- 发送Cookie
在response上提供了发送Cookie相关的方法
- 获取Cookie
在request上提供了获取Cookie相关的方法
没有提供获取特定Cookie的方法,只能通过遍历获取
//获取request中携带的所有cookie组成的数组
Cookie[] cs = request.getCookies();
//遍历所有Cookie
Cookie findC = null;
if(cs!=null){//只有当cs不为null,才可以遍历
for(Cookie c : cs){
//看遍历到的Cookie的名字是否是prod
if("prod".equals(c.getName())){
//是,则保存此Cookie,跳出循环
findC = c;
break;
}
}
}
//判断是否找到了需要的cookie
if(findC!=null){//findC不为null,说明循环过程中找到了需要cookie
//获取Cookie的值,打印
String v = findC.getValue();
System.out.println(v);
}else{//findC为努力了,说明循环过程中没有找到需要的cookie
//打印信息
System.out.println("没有这个Cookie!");
}
- 删除Cookie
response没有提供删除Cookie的方法
可以通过发送一个同名同path但maxAge为0的cookie,就可以删除此cookie了
//创建Cookie
Cookie c1 = new Cookie("prod","");
//--设置超时时间
c1.setMaxAge(0);
//--设置Path
c1.setPath(request.getContextPath());
//发送Cookie
response.addCookie(c1);
- Cookie案例:EasyMall登录 - 记住用户名
a. 通过Cookie保存用户名
LoginServlet
String remname = request.getParameter("remname");
if("true".equals(remname)){
//用户勾选了记住用户名,发送cookie保存用户名
Cookie remnamec = new Cookie("remnamec",username);//创建cookie
remnamec.setMaxAge(60 * 60 * 24 * 30);//保存30天
remnamec.setPath(request.getContextPath());//访问当前应用路径及其子孙路径都要带回来
response.addCookie(remnamec);
}
b. 展示存储的用户名
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/login.css"/>
<title>EasyMall欢迎您登陆</title>
</head>
<body>
<h1>欢迎登陆EasyMall</h1>
<form action="<%=request.getContextPath()%>/LoginServlet" method="POST">
<table>
<tr>
<td colspan="2">
<span>
<font color="red">
<%= request.getAttribute("msg") == null ? "" : request.getAttribute("msg")%>
</font>
</span>
</td>
</tr>
<tr>
<%
//从Cookie中获取记住的用户名
Cookie [] cs = request.getCookies();
Cookie findC = null;
if(cs!=null){
for(Cookie c : cs){
if("remnamec".equals(c.getName())){
findC = c;
break;
}
}
}
String uname = "";
if(findC!=null){
uname = findC.getValue();
}
%>
<td class="tdx">用户名:</td>
<td><input type="text" name="username" value="<%=uname%>"/></td>
</tr>
<tr>
<td class="tdx">密码:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2">
<input type="checkbox" name="remname" value="true"
<%
if(findC!=null){//如果找到了记住用户名cookie,勾选记住用户名选项
%>
checked="checked"
<%
}
%>
/>记住用户名
<input type="checkbox" name="autologin" value="true"/>30天内自动登陆
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="登陆"/>
</td>
</tr>
</table>
</form>
</body>
</html>
c. 删除记住的用户名
LoginServlet
else{
//用户没有勾选记住用户名,则删除之前发送的存储用户名的cookie
Cookie remnamec = new Cookie("remnamec","");
remnamec.setMaxAge(0);
remnamec.setPath(request.getContextPath());
response.addCookie(remnamec);
}