【归纳总结】会话技术 Cookie&Session

  1. 什么叫做会话技术?
    答:服务器与浏览器之间进行一问一答的行为

  2. 为什么要会话技术?
    答:因为HTTP协议其实是一个无状态的协议。对于服务器来说,服务器是无法区别每个HTTP请求时来自于同一个客户端,还是来自于不同的客户端,因为HTTP请求报文全部长得都是一个样,报文里面并没有任何可以表明客户端身份的一个信息。简单来说,服务器不能区分客户端。
    但是,我们有这样的需求:希望服务器能够帮我们客户端去存储一些数据。
    所有,引入专门的会话技术来解决整个问题。

  3. 会话技术有哪些?
    Cookie 和 Session


Cookie

一、什么是cookie

Cookie是一小串数据。数据是由服务器生成的,然后在响应的过程中传给客户端(以set-Cookie响应头的形式发送给客户端),客户端及时保存下来,等到下次访问服务器的时候(以Cookie请求头的形式发回给服务端),就会把这个cookie给携带上。服务器通过解析请求报文就知道谁在访问。
通过键值对的形式可以定义一个Cookie
Cookie是一个实体类,构造方法:
Cookie(java.lang.String name, java.lang.String value)

二、Cookie的应用案例

案例一:显示用户上次访问时间
@WebServlet("/last")
public class LastLoginServlet extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        // cookie的值必须是字符串,并且里面不能有空格
        //获取cookie请求头  cookie:key=value;key=value
        //也就是对于获取cookie请求头的封装
        Cookie[] cookies = request.getCookies();
        if(cookies != null){
    
    
            for (Cookie cookie : cookies) {
    
    
                if("lastLogin".equals(cookie.getName())){
    
    
                    String value = cookie.getValue();
                    long time = Long.parseLong(value);
                    Date date = new Date(time);
                    response.getWriter().println(date);
                }
            }
        }
        Cookie cookie = new Cookie("lastLogin", System.currentTimeMillis() + "");
        //这行代码其实就是对于设置Set-Cookie:key=value的封装
        response.addCookie(cookie);
    }
}
案例二:登陆成功之后跳转到一个个人主页
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        response.setContentType("text/html;charset=utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //不做任何校验,只要输入就当作登录成功
        Cookie cookie = new Cookie("username", username);
        response.addCookie(cookie);
        response.getWriter().println("登录成功,即将跳转至个人主页....");
        response.setHeader("refresh", "2;url=" + request.getContextPath() + "/info");
        //Context域不可以
    }

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

    }
}
@WebServlet("/info")
public class InfoServlet extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        //
        String username = "";
        Cookie[] cookies = request.getCookies();
        if(cookies != null){
    
    
            for (Cookie cookie : cookies) {
    
    
                if("username".equals(cookie.getName())){
    
    
                    username = cookie.getValue();
                }
            }
        }
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>Title</title>\n" +
                "</head>\n" +
                "<body>");

        response.getWriter().println("欢迎您," + username);

        response.getWriter().println("</body>\n" +
                "</html>");
    }
}

三、Cookie的设置

  1. 设置存活时间
cookie.setMaxAge(180);

默认情况下,参数为负数,当参数为负数的时候,cookie仅在浏览器内存中保存,浏览器关闭则cookie失效
如果希望cookie能够进行持久化保存,需要设置一个正数的存活时间,单位是
如果参数设为0,则立即删除该cookie。

  1. 设置路径
cookie.setPath(request.getContextPath() + "/info");

设置path的意义:比如设置某些情况下不需要带cookie,比如请求一个静态资源文件,js、css文件。
默认情况下,如果没有设置path的话,则当访问当前域名下任意资源时,均会带上该cookie,如果想仅部分路径携带cookie,则可以通过设置path来实现。

注意:如果cookie中设置了path,直接设置MaxAge=0不能立即删除cookie。此时需要把设置path的代码再写一遍

cookie.setMaxAge(0);
cookie.setPath(request.getContextPath() + "/info");
response.addCookie(cookie);
  1. 设置域名
cookie.setDomain("octavius.com");

如果没有设置,则cookie默认在当前域名下有效,如果超出当前域名,则失效。

你不可以设置一个和当前域名无关的cookie信息

子域名均可以"继承"得到父域名的cookie

四、细节补充

  1. cookie的name和value值均是字符串类型
  2. cookie它只能存储少量的数据,一般不超过4k
  3. 不同浏览器之间不可以共享cookie

Session

一、什么是Session?

服务器技术。客户端访问服务器上的资源时,服务器会给浏览器开辟一块内存空间,不同的内存空间和对应的浏览器一一绑定,后续如果浏览器想存储数据,直接在对应的内存空间种存储即可。

二、session如何和浏览器关联在一起?

实际上Session底层实现依赖于cookie。

浏览器访问服务器时,服务器会再特定的条件下生成一个session对象,该对象有一个唯一的id,接下来当响应时,会把该session的id 通过cookie返回给当前客户端,客户端接收到该cookie数据之后,随机保存下来;
当下次再次访问服务器其他站点时,会把该cookie重新携带回来,此时服务器可以取出session的id,通过session的id就可以拿到对应的session对象。将当前浏览器和当前session对象关联在一起了。

三、Session的创建

request.getSession();
request.getSession(boolean create)

区别:
在这里插入图片描述
那么,如何判断当前request是否有session对象的呢?
判断当前请求种是否含有一个有效的cookie: JSESSIONID=xxxxxxxxxxxxx,如果有的话,则根据这个id找到对应的session对象;如果没有的话,或者说是一个无效的id,那么这个时候给它创建一个新的session对象。

四、Session发挥功能——Session域

通过下列api对Session中的数据进行操作

session.setAttribute();
session.getAttribute();
session.removeAttribute();

context域、request域、session域的区别:

  • context域:当前应用内只有一个。不同的servlet之间也可以进行共享数据。
  • request域:仅仅在一次请求内有效。
  • session域:当前应用内有多少个浏览器,就有多少个session。范围也比较广。不同的servlet之间也可以进行共享数据。

在实际应用中:

  • session域可以用来存储和用户相关的数据,比如用户的用户名、用户的信息、购物车等
  • context可以用来存储和用户无关的数据,比如当前商城的商品分类,数码、服装、食品

五、Session的销毁

  1. 关闭浏览器session对象会不会销毁?
    不会。此时session对象类似于一种不可达的状态:当关闭浏览器后再用该浏览器访问,服务器会给该浏览器一个新的JSESSIONID。
    但如果一段时间不用,就会被销毁。

  2. 关闭服务器session对象会不会销毁?
    会。关闭服务器或者卸载应用都会销毁session对象。
    但是,session里面的数据不会丢失, session的id以及域里面存储的数据序列化到了本地硬盘上面。
    注意:不要通过关闭idea的tomcat再启动来验证这个过程。因为idea的tomcat每次启动前都会将配置文件删除,重新赋值新的tomcat配置文件过来,所以看不到该现象。
    如果想持久化保存,则需要设置maxAge:

@WebServlet("/session")
public class ServletSession extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        HttpSession session = request.getSession();
        //cookie的name必须为JSESSIONID
        //你创建的这个cookie和浏览器内部的cookie是两个cookie,只不过当你关闭浏览器的时候
        //浏览器内部的cookie就失效了,而你创建的cookie存活了下来
        Cookie cookie = new Cookie("JSESSIONID", session.getId());
        cookie.setMaxAge(60 * 60);
        response.addCookie(cookie);
        session.setAttribute("name", "session");
        //获取JSESSIONID
        String id = session.getId();
        System.out.println(id);
    }
}

  1. 如何主动销毁Session中的数据
    ①有效期到达,session里面的数据会丢失(30min)
    ②主动调用session.invalidate(),将整个session对象失效
    ③session.removeAttribute,仅仅是将一个属性给移除

猜你喜欢

转载自blog.csdn.net/Octavius_/article/details/114503370