1.会话
当用户访问一次浏览器时,获取不同的资源。直到用户将浏览器关闭后,则称为一次会话。
2.作用
Http协议为无状态协议,其无法记录上次访问的内容资源。用户在访问过程中,会产生用户数据,可通过会话将其保留。
3.分类
3.1 cookie
cookie为浏览器端的会话技术。cookie由服务器生成,通过respose对象将cookie传回浏览器端,即通过修改响应头的cookie (set-cookie),保留在浏览器端。下一次访问,浏览器根据一定的规则(即访问路径中包含cookie中的路径),发送request对象的请求头中的cookie。最后,服务器端接收cookie。
3.1.1cookie方法
方法名 | 作用 |
---|---|
new Cookie(String key,String value) | 创建一个cookie |
response.addCookie(Cookie c) | 通过response对象修改响应头传回并保留到浏览器 |
Cookie[] request.getCookies() | 获取所有的cookie |
常用方法 | 用法 |
---|---|
getName() | 获取cookie的key(名称) |
getValue | 获取指定cookie的值 |
setMaxAge(int time) | 设置cookie在浏览器中的最大生存时间,以秒为单位;若设置为0即删除该cookie(前提必须路径一致) |
setPath(String Path) | 设置cookie的路径,cookie的默认路径为访问servlet的路径,从 “/项目名”开始到最后一个“/”结束; 例如:访问路径为/shopping/a/b/Rem ,则其默认路径为 /shopping/a/b |
注:
(1) 可手动设置路径,以 “ 项目名 ” 开始,以 “ / ” 结尾。
(2) 只要cookie的path包含访问路径,请求就会携带对应的cookie
(3)假设浏览器中包含两个cookie
cookie1: name=psw; value=123; path=/shpping/;
cookie2: name=username; value=admin; path=/shopping/servlet/;
也就是说,在访问子路径时,会包含其父路径的Cookie,而在访问父路径时,不包含子路径的Cookie。
//设置编码
response.setContentType("text/html;charset=utf-8");
//创建多个cookie
Cookie cookie1=new Cookie("key1","value1");
Cookie cookie2=new Cookie("key2","value2");
//写回cookie到浏览器
response.addCookie(cookie1);
response.addCookie(cookie2);
//浏览器提示信息
response.getWriter.print("cookie已写回");
(4)如果我们设置path,如果当前访问的路径包含了cookie的路径(当前访问路径在cookie路径基础上要比cookie的范围小)cookie就会加载到request对象之中。
cookie.setPath(request.getContextPath+"/");//获取例如 /shopping/ 的路径
注:通过key值在cookie数组中获取指定的cookie
public class CookUtils {
/**
* 通过名称在cookie数组获取指定的cookie
* @param name cookie名称
* @param cookies cookie数组
* @return
*/
public static Cookie getCookieByName(String name, Cookie[] cookies) {
if(cookies!=null){
for (Cookie c : cookies) {
//通过名称获取
if(name.equals(c.getName())){
//返回
return c;
}
}
}
return null;
}
}
例子:
**
* 案例:记录上次访问的时间
*
*/
public class RemServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应编码
resp.setContentType("text/html;charset=utf-8");
PrintWriter out= resp.getWriter();
//获取全部指定的cookie
Cookie[] cookies=req.getCookies();
Cookie cookie= CookUtils.getCookieByName("lastTime",cookies);
//判断cookie是否为空
if(cookie==null)
{
//第一次访问
out.print("第一次访问");
}
else
{
String value =cookie.getValue();//获得为毫秒数
long time=Long.parseLong(value);
Date date=new Date(time);
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
out.print("上一次访问的时间为"+sdf.format(date));
}
//将当前的访问时间记录
//创建cookie
Cookie cookie1=new Cookie("lastTime",new Date().getTime()+"");
//写回浏览器
resp.addCookie(cookie1);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.1.2cookie运行原理
3.1.2cookie应用
应用一:记录商城浏览记录
/**
* 记录商品浏览器历史
*/
public class GetProductByIdServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.设置编码
//0.1获取当前访问的商品id
String id=request.getParameter("id");
//1.获取指定的cookie ids
Cookie c = CookUtils.getCookieByName("ids", request.getCookies());
String ids="";
//2.判断cookie是否为空
if(c==null){
//若cookie为空 需要将当前商品id放入ids中
ids=id;
}else{
//若cookie不为空 继续判断ids中是否已经该id // ids=2-11-21
//获取值
ids=c.getValue();
String[] arr = ids.split("-");
//将数组转成集合 此list长度不可变
List<String> asList = Arrays.asList(arr);
//将aslist放入一个新可变长的LinkedList中
LinkedList<String> list = new LinkedList<>(asList);
if(list.contains(id)){
//最近浏览的商品会出现在最近的时间段
//若ids中包含id 将id移除 放到最前面
list.remove(id);
list.addFirst(id);
}else{
//若ids中不包含id 继续判断长度是否大于2,即浏览记录显示三个商品
if(list.size()>2){
//长度>=3 移除最后一个 将当前的放入最前面
list.removeLast();
list.addFirst(id);
}else{
//长度<3 将当前放入最前面
list.addFirst(id);
}
}
ids="";
//将list转成字符串
for (String s : list) {
ids+=(s+"-");
}
ids=ids.substring(0, ids.length()-1);
}
//将ids写回去
c=new Cookie("ids",ids);
//设置访问路径
c.setPath(request.getContextPath()+"/");
//设置存活时间
c.setMaxAge(3600);
//写会浏览器
response.addCookie(c);
//3.跳转到指定的商品页面上
response.sendRedirect(request.getContextPath()+"/product_info"+id+".htm");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
应用二:清空浏览记录
/**
*清空浏览记录
*/
public class ClearHistroyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个cookie
Cookie c=new Cookie("ids", "");
c.setPath(request.getContextPath()+"/");// /day1101/
//设置时间
c.setMaxAge(0);
//写会浏览器
response.addCookie(c);
//页面跳转
response.sendRedirect(request.getContextPath()+"/product_list.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
浏览记录显示
<!--
商品浏览记录:
-->
<div style="width:1210px;margin:0 auto; padding: 0 9px;border: 1px solid #ddd;border-top: 2px solid #999;height: 246px;">
<h4 style="width: 50%;float: left;font: 14px/30px " 微软雅黑 ";">浏览记录<small><a href="/day1101/clearHistroy">清空</a></small></h4>
<div style="width: 50%;float: right;text-align: right;"><a href="">more</a></div>
<div style="clear: both;"></div>
<div style="overflow: hidden;">
<ul style="list-style: none;">
<%
//获取指定名称的cookie ids
Cookie c=CookUtils.getCookieByName("ids", request.getCookies());
//判断ids是否为空
if(c==null){
%>
<h2>暂无浏览记录</h2>
<%
}else{//ids=3-2-1
String[] arr=c.getValue().split("-");
for(String id:arr){
%>
<li style="width: 150px;height: 216;float: left;margin: 0 8px 0 0;padding: 0 18px 15px;text-align: center;"><img src="products/1/cs1000<%=id %>.jpg" width="130px" height="130px" /></li>
<%
}
}
%>
</ul>
</div>
</div>
3.2 session
session为服务器端会话技术,用来将用户信息保存在服务器端。当用户第一次访问服务器时,服务器获取Session的id。若能获取到id,在服务器中查找有无此session;若有session,获取session并将用户私有的数据保存在session中,然后将当前session的id通过cookie返回浏览器;若没有session时,服务器需要创建一个session,执行以上操作。若不能获取id时,服务器会创建一个session,将用户信息保存在session中,将当前session的id通过cookie返回浏览器。
常用方法 | 用法 |
---|---|
HttpSession request.getSession() | 获取一个session会话。若存在session,则获取该session;若不存在,则创建一个session |
3.2.1域对象
域对象包括session、servletContext
知识点 | 内容 |
---|---|
生命周期 | 创建:第一次调用request.getSession()创建 销毁:1.服务器非正常关闭 2.session超时,分为两种情况:(1)默认时间超时30分钟(tomcat中conf目录下的web.xml session-config的配置) (2)手动设置 |
常用方法 | 作用 |
---|---|
xxxAttribute | request.getSession().getAttribute / setAttribute() |
invalidate() | 手动删除session |
3.2.2应用
应用一:添加购物车
/**
* 添加到购物车
*/
public class Add2CartServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.设置编码
response.setContentType("text/html;charset=utf-8");
PrintWriter w = response.getWriter();
//1.获取商品的名称
String name=request.getParameter("name");
name=new String(name.getBytes("iso8859-1"),"utf-8");
//2.将商品添加到购物车
//2.1 从session中获取购物车
Map<String,Integer> map=(Map<String, Integer>) request.getSession().getAttribute("cart");
Integer count=null;
//2.2判断购物车是否为空
if(map==null){
//第一次购物 创建购物车
map=new HashMap<>();
//将购物车放入session中g
request.getSession().setAttribute("cart", map);
count=1;
}else{
//购物车不为空 继续判断购物车中是否有该商品
count = map.get(name);
if(count==null){
//购物车中没有该商品
count=1;
}else{
//购物车中有该商品
count++;
}
}
//将商品放入购物车中
map.put(name, count);
//3.提示信息
w.print("已经将<b>"+name+"</b>添加到购物车中<hr>");
w.print("<a href='"+request.getContextPath()+"/product_list.jsp'>继续购物</a> ");
w.print("<a href='"+request.getContextPath()+"/cart.jsp'>查看购物车</a> ");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
应用二:清空购物车
//清空session
request.getSession().invalidate();
request.sendRedict(request.getContextPath()+"/index.jsp");
3.2.3 Session总结
(1) Session会话技术底层依赖于cookie。
(2)