JavaWeb学习笔记五 会话技术Cookie&Session

作者:杏彩彩票app下载

2.2 服务器端接受客户端携带的Cookie

如前面的图中所示,客户端的cookie信息是以请求头的方式发送到服务器端的。因此服务端要获取cookie信息,需要使用request对象中的方法getCookies()。这时唯一的获取cookie的方法,它返回的是Cookie数组集合,因此需要遍历该数组才能获取指定名称的cookie。

例如,获取cookie name为"username"的cookie。

Cookie[] cookies = request.getCookies();
if(cookies != null) {
    for (Cookie coo : cookies) {
        String cookie_name = coo.getName();
        if (cookie_name.equals("username")) {
            String cookie_value = coo.getValue();
            System.out.println(cookie_name+":"+cookie_value);
        }
    }
}
删除客户端的cookie
  • 如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可
//删除客户端保存 name=zhangsan的cookie信息
Cookie cookie = new Cookie("name","");
//将path设置成与要删除cookie的path一致
cookie.setPath("/WEB16");
//设置时间是0
cookie.setMaxAge(0);
response.addCookie(cookie);

获得Session对象

HttpSession session = request.getSession();

此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session 对象会创建一个新的Session返回,如果已经有了属于该会话的Session直接将已有 的Session返回(实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在 session了)

2.1 服务器端向客户端发送Cookie

设置Cookie涉及的几个常用方法为:

  • Cookie(String cookie_name,String cookie_value):构造一个Cookie对象。
  • setPath(uri):当访问属于该uri下的路径(包括子路径)时,该cookie都生效,例如setPath("/Cookie"),当本机使用http://localhost/Cookie/servlet1http://localhost/Cookie/servlet2访问时,都拥有该Cookie。
  • setMaxAge(int second):设置该属性时,cookie将持久化保存到客户端的磁盘中,保存时间为second秒。如果cookie不具有该属性,则cookie只会存放在内存中。
  • setDomain(String domain):设置Cookie生效的域范围,例如cookie.setDomain(".foo.com");,这将对foo.com域下的所有主机都生效(如www.foo.com),但不包括子域(www.abc.foo.com)。

设置好Cookie后,需要使用response的方法addCookie(Cookie cookie)将cookie加入到响应首部中发送给客户端。

例如,以下是名为CooikeDemo工程的一个servlet,该servlet的uri路径为"/cookieservlet"。

import java.io.IOException;
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 CookieServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("username","zhangsan");  //构造cookie对象
        cookie.setPath("/CookieDemo");       //设置cookie生效的uri范围
        cookie.setMaxAge(10*60);             //设置cookie持久到磁盘的时间为10分钟
        response.addCookie(cookie);          //在响应首部中加入set-cookie字段并发送给客户端
    }

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
}

该cookie将会在响应首部加入set-cookie字段发送给客户端:
图片 1

当客户端再次请求时,将在请求首部中加入cookie字段。
图片 2

需要注意的几点:

  • (1).Cookie中不能存储中文。
  • (2).如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭时cookie信息销毁,这是会话级的cookie。如果设置持久化时间,cookie信息会被持久化到磁盘中,这是持久级别的cookie。持久化后的cookie不会随浏览器关闭而失效,而是在有效时间内都有效。
  • (3).setPath()设置的生效路径为目录时,则cookie对该目录和子目录下的资源都生效,如果生效路径为文件时,则只对该文件有效。例如:

    cookie.setPath("/webapp");  //代表访问webapp应用中的任何资源都携带cookie
    cookie.setPath("/webapp/cookieservlet");  //代表访问webapp中的cookieservlet时才携带cookie信息
    
  • (4).如果想要删除当前还有效的cookie信息,可以使用同名同路径的持久化时间为0的cookie进行覆盖。这样一来,每次客户端接收到响应后cookie就立即失效,也就无法携带cookie请求服务端。例如删除上面示例的cookie信息

    Cookie cookie = new Cookie("username","zhangsan");
    cookie.setPath("/CookieDemo");
    cookie.setMaxAge(0);
    response.addCookie(cookie);
    
session
  • Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间存储客户的数据,但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内存空间
  • 服务端开辟了存放session的内存,并把编号发给客户端,客户端存取数据时把session编号带过去
  • session技术是基于cookie的--存储session编号(JSESSONID)
  • 发送编号到服务器,根据编号去寻找session的位置是服务器与客户端自动完成的,不需要自己手动编写代码(session比cookie更容易,就一个api)
  • session是一个域对象
  • 公司给你配了个保险柜放资料,你可以上下班带回家(cookie),但是不安全,容易被人偷或者丢失.也可以放公司的保险柜里(session),但是你需要把钥匙(sessionId)带回家.

手动销毁session

session.invalidate();

3.3 Session对象的生命周期

  • 创建:第一次执行request.getSession()时创建。
  • 销毁:

    • 1.服务器(非正常)关闭时。
    • 2.session过期/失效(默认30分钟,这个默认时间可以在web.xml中修改)。

      <session-config>
        <session-timeout>30</session-timeout>
      </session-config>
      

      需要注意的是失效时间的起算点,即从何时开始计算30分钟?从不操作服务器端的资源开始计时(即从最近一次读取session数据开始)。

    • 3.手动销毁session:session.invalidate();

也就是说,客户端在一次会话中任何资源都共用一个session对象。

问题:浏览器关闭,session就销毁了吗?
不对,session存储在服务端,和客户端没多大关系,只要客户端没有操作session,等一段时间后,session自动销毁。
但是,关闭浏览器后,cookie中的JSESSIONID就丢失了,也就无法再找到对应的session数据。可以在发送session给客户端前将jsessionid当成cookie的属性并配置cookie的持久化时间持久化到客户端磁盘,这样再次打开浏览器时jsessionid就不会丢失。代码大致如下:

HttpSession session = request.getSession();
session.setAttribute("username","Tom");
String id = session.getId();                  //获取JSESSIONID值
Cookie cookie = new Cookie("JSESSIONID",id);  //"JSESSIONID"为固定值
cookie.setPath("/CookieDemo");
cookie.setMaxAge(12*60*60);   //JSESSIONID持久化保存12小时
response.addCookie(cookie);

response.getWriter().write("JSESSIONID:"+id);
System.out.println(session.getAttribute("username"));

 

注:若您觉得这篇文章还不错请点击右下角推荐,您的支持能激发作者更大的写作热情,非常感谢!

Cookie和Session,javacookiesession 1.会话技术简介 http协议是无状态的,因此对于服务端来说,当它接收到客户端的http请求时,无法识别这个...

会话技术
  • 从打开客户端访问某个站点,到关闭这个浏览器的整个过程称为一次会话
  • 会话技术是记录本次会话中客户端的状态与数据
  • 会话技术分为Cookie和Session
  • Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端可以清除cookie
  • Session:将数据存储到服务器端,安全性相对好,增加服务器的压力

从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话。会话技术就是记录这次会话中客户端的状态与数据的。会话技术分为Cookie和Session:

3.Session技术

从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程(释放浏览器内存),成为一次会话。除了Cookie技术可以让服务端在一次会话过程中记住客户端,Session技术也可以达到这样的目的。

Session技术将数据存储在服务器端,它会为每个客户端都创建一块内存空间存储客户端数据,并为客户端分配一个存储在cookie中的JSESSIONID,客户端需要每次都携带一个这个ID,服务器通过这个ID可以找到属于该客户端的内存空间。由于这个标识ID是借助Cookie存储的唯一性标识JSESSIONID,因此Session是基于Cookie来实现的。

图片 3

Session的原理:服务端接收到某客户端首次发送的请求后,为此客户端生成一个session,并分配一段属于该session的缓冲区,同时将该session配对的标识号JSESSIONID作为cookie的name添加到响应首部中返回给客户端;客户端下次访问时,请求首部中将携带该JSESSIONID,服务端将根据该JSESSIONID寻找与之配对的session,如果能找到对应的session,则直接操作该session资源,否则将重新为此JSESSIONID分配一个session和对应的缓冲区。

使用Session技术需要解决如下三个问题:

  • (1).怎样获得属于某客户端的session对象(内存区域)?
  • (2).怎样向session中存取数据?
  • (3).session对象的生命周期?
cookie
  • Cookie技术是将用户的数据存储到客户端的技术
    • 服务器怎么把cookie写给客户端
    • 服务器怎么获取客户端携带的cookie
  • response把cookie信息放在响应头(set-cookie)中返回给客户端

服务器端向客户端发送一个Cookie

1、创建Cookie: Cookie cookie = new Cookie(String cookieName,String cookieValue); ,比如: Cookie cookie = new Cookie("username","zhangsan"); 

那么该cookie会以响应头的形式发送给客户端。注意,Cookie中不能存储中文。

2、设置Cookie在客户端的持久化时间: cookie.setMaxAge(int seconds); ---时间秒 ,注意,如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭 cookie信息销毁(会话级别的cookie),如果设置持久化时间,cookie信息会被持久化到浏览器的磁盘文件里。

比如: cookie.setMaxAge(10*60); ,设置cookie信息在浏览器的磁盘文件中存储的时间是10分钟,过期浏览器 自动删除该cookie信息。

3、设置Cookie的携带路径: cookie.setPath(String path); ,注意,如果不设置携带路径,那么该cookie信息会在访问产生该cookie的 web资源所在的路径都携带cookie信息。

示例: cookie.setPath("/WEB16"); ,代表访问WEB16应用中的任何资源都携带cookie。 cookie.setPath("/WEB16/cookieServlet"); ,代表访问WEB16中的cookieServlet时才携带cookie信息。

4、向客户端发送cookie: response.addCookie(Cookie cookie); 

5、删除客户端的cookie:如果想删除客户端的已经存储的cookie信息,那么就使用同名同路径的持久化时间为0的cookie进行覆盖即可

//设置cookie的最大有效时间
//cookie.setMaxAge(60*60);
//设置为-1 , 就是相当于默认有效时间, 浏览器关闭就消失.
//cookie.setMaxAge(-1);
// 标示cookie的有效时间为0.发送到浏览器就消失了.
//利用有效时间为0 这件事,我们可以做删除cookie的操作.
// 因为同一个路径 ,不能存在相同的cookie(键相同).
// 我们可以通过覆盖的方式,设置有效时间为0. 删除cookie
//cookie.setMaxAge(0);

发送cookie完整代码实例如下:

//1、创建cookie对象
Cookie cookie = new Cookie("name","zhangsan");

//1.1 为cookie设置持久化时间 ---- cookie信息在硬盘上保存的时间
cookie.setMaxAge(10*60);//10分钟 ---- 时间设置为0代表删除该cookie
//1.2 为cookie设置携带的路径
//cookie.setPath("/WEB16/sendCookie");//访问sendCookie资源时才携带这个cookie
cookie.setPath("/WEB16");//访问WEB16下的任何资源时都携带这个cookie
//cookie.setPath("/");//访问服务器下的所有的资源都携带这个cookie

//2、将cookie中存储的信息发送到客户端---头
response.addCookie(cookie);

1.会话技术简介

http协议是无状态的,因此对于服务端来说,当它接收到客户端的http请求时,无法识别这个请求来源于哪个客户端。无状态的协议有优点也有缺点,但对于需要识别客户端甚至是需要记住客户端的业务来说,应当要让http协议"有状态"。

需要记住客户端的业务种类非常多。例如登陆系统,在一个页面登录后,新打开一个该网站页面,应当也保持登录状态。再例如购物车系统,某用户添加商品1后应当保证他还能继续添加商品2,在结算时能够读取购物车中的所有商品。

如何让服务端记住客户端?目前使用最多的是cookie和session两种会话技术。

  • 1.Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端可以清除cookie。
  • 2.Session:将数据存储到服务器端,安全性相对好,会增加服务器的压力。
向session中存取数据
  • session也是一个域对象
session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);

怎样向session中存取数据(session也是一个域对象)

Session也是存储数据的区域对象,所以session对象也具有如下三个方法:

session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);

Java Cookie和Session,javacookiesession

创建/获取Session对象
  • 获得专属于当前会话的Session对象,如果服务器端没有该会话的Session对象会创建一个新的Session返回
  • 如果已经有了属于该会话的Session直接将已有 的Session返回
  • 实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在session了
//创建属于该客户端的session对象,如果存在,则获取
HttpSession session = request.getSession();

浏览器关闭,session就销毁了? 

没有,存在于浏览器上的唯一标识符JSESSIONID(sessionid)消失了,但是服务器中存放的sessionid并没有立马销毁。

  • 当在同一个浏览器中同时打开多个标签,发送同一个请求或不同的请求,仍是同一个session;
  • 当不在同一个窗口中打开相同的浏览器时,发送请求,仍是同一个session;
  • 当使用不同的浏览器时,发送请求,即使发送相同的请求,是不同的session;
  • 当把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时,是不同的session。

验证码案例:

图片 4图片 5

package session;

import cn.dsna.util.images.ValidateCode;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by yang on 2017/7/24.
 */
public class SessionDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
//1 生成验证码
        ValidateCode code = new ValidateCode(200, 80, 4, 100);
//2 将验证码保存到session中
        System.out.println(code.getCode());
        request.getSession().setAttribute("code", code.getCode());
//3 将验证码图片输出到 浏览器
        resp.setContentType("image/jpeg");
        code.write(resp.getOutputStream());
    }
}

SessionDemo

图片 6图片 7

<%--
  Created by IntelliJ IDEA.
  User: yang
  Date: 2017/7/23
  Time: 11:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>$Title$</title>
</head>
<body>
<form action="/DServlet" method="post">
    验证码: <input type="text" name="code"/><img src="/SessionDemo" width="150" id="one" onclick="fun1();"/>
    <a href="javaScript:void(0)" onclick="fun1();">看不清换一张</a><br>
    <input type="submit" value="登录"/> <br>
</form>

<%=request.getAttribute("error")==null?"":(String)request.getAttribute("error") %>
</body>
</html>
<script type="text/javascript">
    function fun1() {
        //1  获得img对象
        var img = document.getElementById("one");
        //2 改变img对象 src属性
        img.src = "/SessionDemo?abc=" + new Date();

    }

</script>

index.jsp

图片 8图片 9

package session;

import cn.dsna.util.images.ValidateCode;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by yang on 2017/7/24.
 */
public class DServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
        //1 获得表单提交的验证码
        String code1 = request.getParameter("code");
        //2 获得session中的正确验证码
        String code2 =     (String) request.getSession().getAttribute("code");
        //3 比对是否一致
        if(code1!=null && code2!=null && code1.equals(code2)){
            //正确==> 成功页面
            resp.sendRedirect("/index.jsp");
        }else{
            //不正确==> 回到表单 页面 ,提示错误
            request.setAttribute("error", "验证码错误!请重新输入");
            request.getRequestDispatcher("/index.jsp").forward(request, resp);
        }
    }
}

DServlet

本文由杏彩发布,转载请注明来源

关键词: