JAVA EE-SESSION&COOKIE
应该相信,自己是生活的战胜者。 —— 雨果
什么是会话技术?
- 会话的概念:
日常生活来讲.会话就是两个人聊天. 聊天的前提,聊天双方需要有记忆力. 在聊的过程中,都是基于之前聊的状态,继续往下聊.
我们javaweb中,浏览器和服务器也可以看作是双方在聊天(请求,响应). 浏览器服务器双方也需要有”记忆力”,保存之前的聊天状态.服务器和浏览器才可以完成会话. - 会话的范围:
两个从打招呼到两人互相道别.是一次会话.
打开网站,完成我们想做的需求,到关闭浏览器.是一次会话.
Cookie: 让浏览器能够记录信息.
Session:让服务器端能够记录信息.
Cookie与Session的图解
详解Cookie技术
演示向浏览器发送cookie头
//演示发送cookie(头)到浏览器
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//明白原理的写法:
//response.setHeader("set-Cookie", "name=tom");
//使用封装好的代码
//创建cookie对象 => 封装键值对
Cookie cookie = new Cookie("name",URLEncoder.encode("汤姆","UTF-8"));
//将cookie添加到response中 => 添加响应头
response.addCookie(cookie);
}
}
演示如何取出浏览器发出来的cookie
//演示取出浏览器发送过来的cookie
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获得浏览器发送的所有cookie
Cookie[] cookies = request.getCookies();
Cookie nameCookie = null;
//遍历,找到我们要找的cookie
if(cookies!=null){
for(Cookie c : cookies){
if("name".equals(c.getName())){
//找到了
nameCookie = c;
}
}
}
if(nameCookie!=null){
System.out.println("浏览器发送的cookie==>" + nameCookie.getName()+":"+nameCookie.getValue());
System.out.println("浏览器发送的cookie==>" + nameCookie.getName()+":"+URLDecoder.decode(nameCookie.getValue(), "UTF-8"));
}else{
System.out.println("没有找到namecookie");
}
}
}
令人十分不解的是,SUN公司还没有对取出cookies进行优化,如果想取出特定键,必须遍历后判断。
但是我们可以通过自己封装一个工具类来实现取出特定Cookie的目的。
public class CookieUtils {
public static Cookie getCookieByName(HttpServletRequest request,String name){
Cookie cookie = null;
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(Cookie c: cookies){
if(name.equals(c.getName())){
cookie = c;
}
}
}
return cookie;
}
}
设置cookie在何时后过期
public class CServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie c = new Cookie("name","jerry");
//设置cookie的有效时间
c.setMaxAge(60*60*24*7*2);//告诉浏览器保存2周
//c.setMaxAge(-1);// -1代表 在会话结束时删除cookie(默认情况)
//c.setMaxAge(0);// 通常用于删除已经存在的cookie.使用一个寿命为0的cookie,覆盖要删除的cookie
response.addCookie(c);
}
}
设置Cookie的路径
public class DServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie c = new Cookie("name","jack");
//设置Cookie的路径
c.setPath("/day09-cookie/ABC");
response.addCookie(c);
}
}
保存访问的历史纪录
public class EServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.获得参数
String name = request.getParameter("name");
// 2.获得Cookie
Cookie history = CookieUtils.getCookieByName(request, "history");
if(history!=null){
// //存在 => 修改cookie加上现在浏览器的品牌 => dell,hp,lenvo
if(!history.getValue().contains(name)){
history = new Cookie("history",history.getValue()+","+name);
}
}else{
// //不存在 => 创建cookie
history = new Cookie("history",name);
}
// 3.将cookie发送会浏览器
response.addCookie(history);
// 4.重定向到列表页面
response.sendRedirect("/day09-cookie/history/list.jsp");
}
}
记住用户名与密码
public class FServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.获得用户名密码
String name = request.getParameter("name");
// 2.校验用户名密码
if(name==null || "".equals(name.trim())){
// //失败=> 转发到表单页面,并提示错误
request.setAttribute("error", "请输入用户名!");
request.getRequestDispatcher("/remember/login.jsp").forward(request, response);
return;
}
// 3.创建cookie 添加要保存的用户名,
Cookie c = new Cookie("remember", name);
// 4.查看记住用户名是否被选中
String remember = request.getParameter("remember");
if("yes".equals(remember)){
// 选中 => 设置保存时间为2周
c.setMaxAge(60*60*24*7*2);
}else{
// //没选中=>设置保存事件为0
c.setMaxAge(0);
}
// 5.添加到响应中
response.addCookie(c);
// 6.重定向到成功页面
response.sendRedirect("/day09-cookie/index.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Session技术详解
如何获取Session对象
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//参数类型是boolean型
//true=> 无论如何都要获得session
//false => 如果没有sessionID ,不会获得session
//request.getSession(true);
HttpSession session = request.getSession();//相当于上面的方法 填写true
//session 的操作
// session.setAttribute(arg0, arg1)
// session.getAttribute(arg0)
// session.getAttributeNames()
// session.removeAttribute(arg0)
//session中可以存放登录状态
}
}
关于session对象的一些操作
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
System.out.println("session.isNew()"+session.isNew());// 判断session是否 是新的.
System.out.println("session.getCreationTime()"+new Date(session.getCreationTime()));//获得session的创建时间
System.out.println("session.getId()"+session.getId());//获得session的id
System.out.println("session.getLastAccessedTime()"+new Date(session.getLastAccessedTime()));//获得最后一次的访问时间
System.out.println("session.getMaxInactiveInterval()"+session.getMaxInactiveInterval());// 获得session的最大有效时间
//session.setMaxInactiveInterval(60);//设置session的最大有效时间为60秒
session.invalidate();//*** 立即让session销毁.
}
}
Session的一些细节问题
Session的细节
1.Session的有效时间
默认:
30分钟
手动指定:
* tomcat/conf/web.xml => <Session-timeout>
* 项目/WEB-INF/web.xml => <Session-timeout>
* 代码: session.setMaxInactiveInterval(); 每次调用只影响被调用的session对象
2.Session的作用范围
一个会话期间
会话结束:
1.浏览器关闭
2.Session的过期
3.手动调用销毁Session的方法
3.Session中的其他API
Session.invalidate() => 立即销毁Session对象
利用Session与Cookie技术完成两个实例的制作
购物车
先构建左侧的购物车区域
</head>
<body>
<h1>商品列表</h1>
<table border="1" >
<tr>
<td>
<img src="/day09-cart/img/pic (1).jpg" width="300" height="200" /><br>
肥皂<br>
<a href="/day09-cart/AServlet?name=0" >点击加入购物车</a>
</td>
<td>
<img src="/day09-cart/img/pic (2).jpg" width="300" height="200" /><br>
蜡烛<br>
<a href="/day09-cart/AServlet?name=1" >点击加入购物车</a>
</td>
</tr>
<tr>
<td>
<img src="/day09-cart/img/pic (3).jpg" width="300" height="200" /><br>
被罩<br>
<a href="/day09-cart/AServlet?name=2" >点击加入购物车</a>
</td>
<td>
<img src="/day09-cart/img/pic (4).jpg" width="300" height="200" /><br>
枕头<br>
<a href="/day09-cart/AServlet?name=3" >点击加入购物车</a>
</td>
</tr>
</table>
<a href="/day09-cart/cart.jsp" >查看购物车</a>
</body>
</html>
Servlet的业务逻辑代码
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0 准备数组,与页面商品对应
String[] products = {"肥皂","蜡烛","被罩","枕头"};
// 1. 获得当前请求要添加的商品
String indexStr = request.getParameter("name");// 0 ~ 3
String productName = products[Integer.parseInt(indexStr)];
// 2.从Session中取出存放购物车的map
Map<String,Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");
if(cart==null){
// //取不到=>初始化map,
cart = new LinkedHashMap<String, Integer>();
//并放入session
request.getSession().setAttribute("cart", cart);
}
// 3.使用当前要添加的商品从map中取值
Integer count = cart.put(productName, 1);
if(count!=null){
cart.put(productName, count+1);
}
// //取不到=> 放入map,设置数量为1
// //取得到=> 将数量+1放回去
// 4.重定向回商品列表页面
response.sendRedirect("/day09-cart/list.jsp");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
用于显示输出的JSP
** </head>
<body>
<h1>购物车</h1>
<table border="1">
<tr>
<th>商品名称</th>
<th>商品数量</th>
</tr>
<%
Map<String,Integer> cart = (Map<String,Integer>)session.getAttribute("cart");
if(cart!=null && cart.size()>0){
for(Entry<String,Integer> en : cart.entrySet()){
%>
<tr>
<td><%=en.getKey() %></td>
<td><%=en.getValue() %></td>
</tr>
<% }
}
%>
</table>
</body>
</html>**
验证码
生成验证码并且发送给浏览器的代码逻辑
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0设置正文类型
response.setContentType("image/jpeg");
//1 生成验证码
ValidateCode code = new ValidateCode(150, 70, 4, 2);
//2 将正确答案放入Session
String str = code.getCode();
request.getSession().setAttribute("code", str);
System.out.println(str);
//3 将图片流发送给浏览器
code.write(response.getOutputStream());
}
}
获取并且判断
public class BServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 获得用户填写的验证码
String code1 = request.getParameter("code");
//2 获得Session中正确的
String code2 = (String) request.getSession().getAttribute("code");
//3 比对
if(code1!=null && code1.equalsIgnoreCase(code2)){
//成功=> 登录成功 => 重定向到登录页面
response.sendRedirect("/day09-checkcode/index.jsp");
}else{
//失败=> 转发到登录页面并提示
request.setAttribute("error", "请输入正确的验证码");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
最终显示的JSP代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript">
function fun1(){ // 改变img标签的src属性值
//1 获得img标签对象
var img = document.getElementById("one");
//2 改变src属性
img.src = "/day09-checkcode/AServlet?date="+new Date();
}
</script>
</head>
<body>
<form action="/day09-checkcode/BServlet" >
用户名:<input type="text" name="name" /> <br>
密码:<input type="text" name="password" /><br>
验证码:<input type="text" name="code" size="4" /><img id="one" src="/day09-checkcode/AServlet" >
<a href="javaScript:void(0)" onclick="fun1();" >看不清,换一张</a>
<font color="red" >${requestScope.error}</font>
<br>
<input type="submit" value="登录" />
</form>
</body>
</html>