会话技术—cookie
1.会话技术概述
在浏览器和服务器建立连接之后,浏览器和服务器为了完成某一个功能 ,浏览器发出一次或者多次请求,浏览器做出一次或者多次响应,在浏览器关闭之前,所有的请求和响应就构成了一次会话。
2.HTTP协议的特特点
http无状态协议:当前请求和上一次请求没有任何的联系
3.使用会话技术的原因:
a.为了能够在多次请求和响应之间共享数据,所以提出会话技术
4.会话技术—cookie
a.cookie的实现原理
服务器会在第一次响应的时候,通过set-cookie响应头,将需要使用的数据发送到浏览器,浏览器会自动将其作为cookie保存,在下一次请求时,会自动携带一个cookie请求头,其中包含的内容就是浏览器中的cookie信息。cookie技术是一门浏览器端的技术。
b.cookie的特点:
cookie是一门浏览器端的技术,数据保存在浏览器端。保存安全性较低的数据,且存储时间较长的数据。
b.案例:返回上次访问页面的时间:
i.在第一次响应中,set-cookie保存的数据会到达浏览器。并且保存在浏览器中。
ii.在下一次的请求中,使用cookie请求头,获取cookie,得到结果。
package cn.tedu.cookie;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//cookie原理实现
public class CookieDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
/*PrintWriter out = response.getWriter();*/
//返回页面上一次的访问时间
Date date=new Date();
String time=date.toLocaleString();
//设置set-cookie响应头
response.setHeader("set-cookie", "time:="+time);
//获取请求头cookie
String cookie=request.getHeader("cookie");
//打印结果
if(cookie==null){
response.getWriter().write("您是初次访问本页面 ");
}
response.getWriter().write("上次访问的时间:"+cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.tedu.cookie;
//cookie类实现返回上次访问的时间
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieDemo2 extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取时间
Date date=new Date();
String time=date.toLocaleString();
//创建cookie
Cookie cookie=new Cookie("time", time);
//发送cookie
response.addCookie(cookie);
//获取cookie
Cookie[] cs = request.getCookies();
Cookie timeC=null;
if(cs!=null){//初次访问页面时没有任何的cookie,所以会产生空指针异常
for (Cookie c : cs) {
if("time".equals(c.getName())){
timeC=c;//当前cookie对象范围过小,无法在外侧代码进行操作,可以赋值给更大范围的cookie
}
}
}
//打印结果
if(timeC==null){
response.getWriter().write("你是初次访问");
}
response.getWriter().write("上次访问的时间:"+timeC.getValue());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5.cookie类
sun公司提供的一个cookie类,可以通过创建对象的方式来创建cookie
a.创建cookie
Cookie cookie=new Cookie(String name,value);
b.设置cookie的生命时长
cookie的生命时长可以设置也可以不设置,如果不设置当前cookie为一个会话级别的cookie,关闭浏览器当前cookie就会销毁,如果设置生命时长,则达到对应的时间之后,会有浏览器自动销毁。
cookie.setMaxAge(秒);
c.设置有效路径
如果不设置有效路径,则当前cookie的有效路径为资源名称部分,在这一部分中可以共享cookie。如果设置有效路径,则为整个web应用,那么在整个web应用的虚拟路径级别之下都可以获取到当前的cookie。
cookie.setpath();
d.发送cookie
response.addCookie()
e.获取cookie
request.getCookie()----Cookie[]
f.删除cookie
发送一个与要删除的cookie完全相同的cookie,并且设置他的生命时长为0,则这个cookie就可以销毁,完全相同的cookie需要包则会那个name+path+domain三者完全一致
g.案例:通过cookie实现,页面上次访问的时间
package cn.tedu.cookie;
//cookie类实现返回上次访问的时间
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieDemo3 extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取时间
Date date=new Date();
String time=date.toLocaleString();
//创建cookie
Cookie cookie=new Cookie("time", time);
//设置cookie
//生命时长
cookie.setMaxAge(60*60*24*30);
//设置有效路径(web应用开头---/day12或者虚拟路径开头+"/")
cookie.setPath(request.getContextPath()+"/");
//发送cookie
response.addCookie(cookie);
//获取cookie
Cookie[] cs = request.getCookies();
Cookie timeC=null;
if(cs!=null){//初次访问页面时没有任何的cookie,所以会产生空指针异常
for (Cookie c : cs) {
if("time".equals(c.getName())){
timeC=c;//当前cookie对象范围过小,无法在外侧代码进行操作,可以赋值给更大范围的cookie
}
}
}
//打印结果
if(timeC==null){
response.getWriter().write("你是初次访问");
}
response.getWriter().write("上次访问的时间:"+timeC.getValue());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.tedu.cookie;
//删除cookie
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieDemo4 extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//删除cookie就是发送一个域要删除的cookie的name和path完全相同的cookie
//并且生命时长为0
Cookie cookie=new Cookie("time", "");
//设置生命时长
cookie.setMaxAge(0);
//设置有效路径
cookie.setPath(request.getContextPath()+"/");
//发送cookie到浏览器,覆盖原有的cookie
response.addCookie(cookie);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
6.EasyMall功能实现–记住用户名
a.导入login.jsp
b.修改_head.jsp
c.创建LoginServlet.java
d.修改login.jsp
cookie中中文乱码
Cookie cookie=new Cookie("remname",URLEncoder.encode(username, "utf-8"));
username=URLDecoder.decode(remnameC.getValue(), "utf-8");
会话技术–session
1.session概述:
在浏览器端保存数据,数据可以被查看、获取,数据安全性较低。重要的数据应该保存在不容易被获取到的位置,服务器是一个良好的选择,数据通过服务器共享,这门技术就是session技术。
2.session工作原理
每一个浏览器在访问服务器时,都会创建各自对应的session对象来保存数据,相互之间不会影响,是因为在session对象身上会包含一个sessionid,可以通过这个id来区分每一个浏览器对应的session。
a.本质是通过一个名为JSESSIONID的cookie来工作的,这个cookie会保存在浏览器中使用。
b.session的特点:
session是一门服务器的技术,将数据保存到服务器端,保存的安全性要求较高的数据,但是可以存储时间较短的数据。
3.创建session对象
request.getSession();//如果服务器有对象则拿出使用,如果没有对象则创建一个新的session对象使用。
request.getSession(true);//如果服务器中有session对象,则取出使用,如果没有session对象则创建一个新的session对象使用。
request.getSession(false);//如果服务器中没有session对象,则返回null,如果有session对象则取出使用。(判断session是否存在时使用)
4.作为域对象使用
域对象:如果一个对象身上有一个可以被看见的范围,在这个范围内利用对象身上的map实现数据的共享,这个对象就可以称之为域对象。
a.操作的api
setAttribute()设置域属性
getAttribute()获取域属性
removeAttribute()删除域属性
getAttributeNames()获取所有的域属性名称
b.生命周期:
request.getSession()方法调用的时候session对象产生
i、意外身亡:在服务器意外关闭的情况下,session对象会被销毁。在服务器正常关闭的情况下,如果session对象未被释放,则其中的内容会被序列化到磁盘上,这个过程称之为钝化,当服务器再次启动的时候,会重新读取磁盘上这个文件,这个过程称之为活化。
ii、自杀:主动调用session.invalidate()方法会立刻释放当前的session对象
iii、超时死亡:在tomcat/conf/web.xml中有session最大的生命时长配置(session-config标签),默认值为30分钟,超过30分钟,则当前session会被释放。
c.作用范围
整个会话范围
d.主要功能
在整个会话范围内共享数据
代码实现:
package cn.tedu.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//session共享数据,作为域对象使用
public class SessionDemo1 extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();*/
//获取session对象
HttpSession session = request.getSession();
//设置域属性
session.setAttribute("name", "曹阳");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.tedu.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//session共享数据,作为域对象使用
public class SessionDemo2 extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();*/
//获取session对象
HttpSession session = request.getSession(true);
//获取域属性
String name=(String) session.getAttribute("name");
System.out.println("name>>"+name);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
购物车案例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" session="false"%>
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=鼠标">鼠标</a><br>
<a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=键盘">键盘</a><br>
<a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=月饼">月饼</a><br>
<a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=手机">手机</a><br>
<a href="http://localhost/day12-cookiesession/servlet/BuyServlet?prod=拖鞋">拖鞋</a><br>
<a href="http://localhost/day12-cookiesession/servlet/PayServlet">付款</a><br>
</body>
</html>
package cn.tedu.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//这是一个购物车
public class BuyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//请求乱码处理
String prod=request.getParameter("prod");
prod=new String(prod.getBytes("iso8859-1"),"utf-8");
//响应乱码处理
response.setContentType("text/heml;charset=utf-8");
//把商品放入购物车
HttpSession session = request.getSession();
//在浏览器前后都要操作同一个session---在浏览器端保存一个名称为JSESSIONID的cookie,
//cookie的值存储session的值
Cookie cookie=new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60*60*24);
cookie.setPath(request.getContextPath()+"/");
response.addCookie(cookie);
//向session中添加域属性
session.setAttribute("prod",prod);
//在浏览器中提示商品已加入购物车
response.getWriter().write("商品"+prod+"已加入购物车");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
package cn.tedu.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//这是一个支付servlet
public class PayServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//判断session是否存在
if(request.getSession(false)!=null){
//如果存在则取出域属性
String prod=(String) request.getSession().getAttribute("prod");
//释放session
request.getSession(false).invalidate();
response.getWriter().write("您已经为商品"+prod+"付款¥10000");
}else{//如果不存在则表示用户未选择商品
response.getWriter().write("您未选择商品");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5.EasyMall功能实现–登录
通过登录功能,保存用户的登录状态
request域 范围台太小
servletcontext域 范围太大
session域合适
a.修改LoginServlet.java
b.在login.jsp页面加入脚本语句
6.注销功能
7.验证码
扩展:
修改web应用名称的方法: