cookie&session&jsp

第一章-会话

1.会话的概念

​用户打开浏览器,浏览不同的网页(资源),发出多个请求,直到关闭浏览器的过程,称为一次会话(多次请求). 如同打电话.

​我们在会话的过程(多次请求)之中,用户可能会产生一些数据,这些数据话有的需要保存起来的,我们就可以通过会话技术来保存用户各自的数据

2.为什么要使用会话技术

保存用户各自(以浏览器为单位)的数据

3.常用的会话技术

3.1.1cookie

cookie是客户端(浏览器)端的技术,用户浏览的信息以键值对(key=value)的形式保存在浏览器上。如果没有关闭浏览器,再次访问服务器,会把cookie带到服务端,服务端就可以做响应的处理。

3.1.2session

session是服务器端的技术。服务器为每一个浏览器开辟一块内存空间,即session。由于内存空间是每一个浏览器独享的,所有用户在访问的时候,可以把信息保存在session对象中。同时,每一个session对象都对应一个sessionId服务器把sessionId写到cookie中,再次访问的时候,浏览器会把cookie(sessionId)带过来,找到对应的session对象

第二章-Cookie

2.1 Cookie的概念

cookie&session&jsp_第1张图片
​Cookie是一种客户端的会话技术,它是服务器存放在浏览器的一小份数据,浏览器以后每次访问该服务器的时候都会将这小份数据携带到服务器去。

2.2 Cookie的作用

  1. 在浏览器中存放数据
  2. 将浏览器中存放的数据携带到服务器

2.3 Cookie的应用场景

1.记住用户名
当我们在用户名的输入框中输入完用户名后,浏览器记录用户名,下一次再访问登录页面时,用户名自动填充到用户名的输入框.
cookie&session&jsp_第2张图片

2.自动登录(记住用户名和密码)
当用户在淘宝网站登录成功后,浏览器会记录登录成功的用户名和密码,下次再访问该网站时,自动完成登录功能.
以上这些场景都是使用会话cookie实现的,将上次的信息保存到了cookie中,下次直接从cookie中获取数据信息
cookie&session&jsp_第3张图片

3.保存网站的上次访问时间
我们访问网站的时候,通常会看到网站上显示上次访问时间,这些信息就是在用户访问网站的时候保存在cookie中的

4.保存电影的==播放进度 ==

​ 在网页上播放电影的时候,如果中途退出浏览器了,下载再打开浏览器播放同一部电影的时候,会自动跳转到上次退出时候的进度,因为在播放的时候会将播放进度保存到cookie中

Cookie的快速入门

相关的API

  • 创建一个Cookie对象(cookie只能保存字符串数据。且不能保存中文)
new Cookie(String name,String value);
  • 把cookie写回浏览器
response.addCookie(cookie); 
  • 获得浏览器带过来的所有Cookie:
request.getCookies() ; //得到所有的cookie对象。是一个数组,开发中根据key得到目标cookie
  • cookie的 API
cookie.getName() ; //返回cookie中设置的key
cookie.getValue(); //返回cookie中设置的value

入门代码

    //第一次是服务器通过response 响应给客户端
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
        //获得所有的cookie
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
     
            for (Cookie cookie : cookies) {
     
                //获得name是akey的cookie对象, 以及它的value
                if("akey".equals(cookie.getName())){
     
                    System.out.println(cookie.getValue());
                }
                //获得cookie的name和value
                //System.out.println(cookie.getName() + "=" + cookie.getValue());
            }
        }


        //创建Cookie
        Cookie aCookie = new Cookie("akey", "aaa");
        Cookie bCookie = new Cookie("bkey", "bbb");
        //写给浏览器
        response.addCookie(aCookie);
        response.addCookie(bCookie);


        response.getWriter().print("ServletDemo01");


    }

小结

  1. cookie特点

    • Cookie保存在客户端(浏览器端的)
    • 第一次请求的时候, 没有Cookie的, 先由服务器写给浏览器.
    • Cookie里面只能保存字符串, 大小有限制
  2. cookie相关API

    • new Cookie(String name,String value); 创建Cookie
    • response.addCookie(cookie); 把Cookie写给浏览器
    • request.getCookies(); 获得所有的Cookie对象
    • cookie.getName() 获得Cookie的key
    • cookie.getValue() 获得Cookie的value

    Cookie本质是请求头,响应头

  3. 我们一般根据cookie的name获得目标cookie对象. 我们可以把这块逻辑封装到工具类里面

/**
 * @Description: Cookie的工具类
 * @Author: yp
 */
public class CookieUtils {
     

    //根据key从所有的Cookies里面获得目标Cookie对象
    public static Cookie getTargetCookie(String key,Cookie[] cookies){
     
        //1. 非空判断
        if(cookies == null){
     
            return null;
        }

        //2.遍历, 根据key获得目标Cookie返回
        for (Cookie cookie : cookies) {
     
            if(key.equals(cookie.getName())){
     
                return cookie;
            }
        }

        return null;

    }

}

Cookie进阶

cookie的分类

  • 会话级别cookie

​ 在默认的情况下,当浏览器进程结束(浏览器关闭,会话结束)的时候,cookie就会消失。

  • 持久性cookie

    ​ 给cookie设置有效期.cookie.setMaxAge(int expiry) :时间是秒

    ​ -1:默认。代表Cookie数据存到浏览器关闭(保存在浏览器文件中)。

        正整数:以秒为单位保存数据有有效时间(把缓存数据保存到磁盘中)    
    

    ​ 0:代表删除Cookie.如果要删除Cookie要确保路径一致

cookie设置有效路径

setPath(String url) ;设置路径

​ 有效路径作用 :

  1. 保证不会携带别的网站/项目里面的cookie到我们自己的项目
  2. 如果路径不一样, cookie的key可以相同
  3. 保证自己的项目可以合理的利用自己项目的cookie
  • 默认路径,例如:

    • 访问http://localhost:8080/web18A_Cookie/demo01; cookie默认路径 /web18A_Cookie
    • 访问http://localhost:8080/web18A_Cookie/aaa/demo01; cookie默认路径 /web18A_Cookie/aaa

    • 访问http://localhost:8080/web18A_Cookie/aaa/bbb/demo01; cookie默认路径 /web18A_Cookie/aaa/bbb

  • 随带Cookie需要的条件: ==只有当访问资源的url包含此cookie的有效path的时候,才会携带这个cookie;==反之不会.

    • eg: 设置cookie的路径 /demo02

      下次访问路径:http://localhost:8080/day30a-cookie/demo02/ccc; cookie是可以带过来

      下次访问路径:http://localhost:8080/day30a-cookie/demo03; cookie带不过来

  • cookie的路径通常设置 / 或者 /发布项目名设置的有效是 /day30a-cookie. 当前项目下的Servlet都可以使用该cookie. 一般这么设置: cookie.setPath(request.getContextPath());

    只要是当前项目里面的资源 路径必须包含项目名路径.

小结

  1. Cookie的类型

    • 会话级别【默认的】 浏览器关闭了就消失了
    • 持久级别 setMaxAge(int 秒)
      • -1 默认值
      • 正整数
      • 0 删除cookie 【必须路径一致】
  2. cookie有效路径 cookie.setPath(String path) 建议设置成当前的项目部署路径; setPath(request.getContextPath())

  3. cookie的弊端 cookie的大小(个数和自身大小)和格式(只能存字符串)有限制,默认不支持中文,解决中文办法

URLEncode.encode(value,"utf-8");//存入的时候(先通过utf-8编码)
URLDecode.decode(value,"utf-8");//取出 (通过utf-8解码)

记录用户各自的上次访问时间

1.需求

cookie&session&jsp_第4张图片

​ 在访问一个资源的时候,展示上次访问的时间

​ 若是第一次访问则展示:你是第一次访问,若不是第一次则展示:你上次访问的时间是:xxxx

2.分析

cookie&session&jsp_第5张图片

3.代码实现

package com.itheima.web;

import com.itheima.utils.CookieUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Description:
 * @Author: yp
 */
@WebServlet("/rem")
public class RememberServlet extends HttpServlet {
     

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
         //解决乱码
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        //1.判断是否是第一次访问(说白了判断目标cookie是否为null)
        Cookie[] cookies = request.getCookies();
        Cookie targetCookie = CookieUtils.getTargetCookie("lastTime", cookies);
        if(targetCookie == null){
     
            //2.为null, 第一次访问
            //2.1记录当前的时间到Cookie
            Cookie cookie = new Cookie("lastTime", System.currentTimeMillis() + "");
            cookie.setMaxAge(60*60*24);
            cookie.setPath(request.getContextPath());
            response.addCookie(cookie);
            //2.2响应'你是第一次访问'
            response.getWriter().print("你是第一次访问");
        }else{
     
            //3. 不为null 不是第一次访问
            //3.1 记录当前的时间到Cookie
            Cookie cookie = new Cookie("lastTime", System.currentTimeMillis() + "");
            cookie.setMaxAge(60*60*24);
            cookie.setPath(request.getContextPath());
            response.addCookie(cookie);

            //3.2 从cookie获得上次的访问的时间 响应
            String timeStr = targetCookie.getValue();
            Date date = new Date(Long.parseLong(timeStr));
            response.getWriter().print("你上次访问的时间是:"+date.toLocaleString());
        }


    }

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


第三章-Session

3.1session概述

​session是服务器端的技术。服务器为每一个浏览器开辟一块内存空间,即session对象。由于session对象是每一个浏览器特有的,所有用户的记录可以存放在session对象中。同时,每一个session对象都对应一个sessionId,服务器把sessionId写到cookie中,再次访问的时候,浏览器把sessionId带过来,找到对应的session对象

3.2cookie和Session的不同

  • cookie是保存在浏览器端的,大小和个数都有限制。session是保存在服务器端的, 原则上大小是没有限制(实际开发里面也不会存很大大小), 安全一些。
  • cookie不支持中文,并且只能存储字符串;session可以存储基本数据类型,集合,对象

3.3Session的执行原理

​ 1、获得cookie中传递过来的SessionId(cookie)

​ 2、如果Cookie中没有sessionid,则创建session对象

​ 3、如果Cookie中有sessionid,找指定的session对象

​ 如果有sessionid并且session对象存在,则直接使用

​ 如果有sessionid,但session对象销毁了,则执行第二步

cookie&session&jsp_第6张图片

Session的基本使用

范围: 会话(多次请求) 保存用户各自的数据(以浏览器为单位)

  • request.getSession(); 获得session(如果第一次调用的时候其实是创建session,第一次之后通过sessionId找到session进行使用)
  • Object getAttribute(String name) ;获取值
  • void setAttribute(String name, Object value) ;存储值
  • void removeAttribute(String name) ;移除

小结

  1. Session基本使用: 作为域对象存取数据 范围: 一次会话(多次请求, 用户各自的) 不同的浏览器session不一样

    • Object getAttribute(String name) ;获取值

    • void setAttribute(String name, Object value) ;存储值

    • void removeAttribute(String name) ;移除

  2. 浏览器关闭了, session使用不了, 是session销毁了吗?

    ​ session没有销毁.

    ​session基于cookie, sessionId保存到cookie里面的, 默认情况下cookie是会话级别,浏览器关闭了cookie就是消失了,也就是说sessionId消失了, 从而找不到对应的session对象了, 就不能使用了.

    ​ 解决: 自己获得sessionId, 自己写给浏览器 设置Cookie的有效时长, 这个Cookie的key必须: JSESSIONID

三个域对象比较

1.三个域对象比较

域对象 创建 销毁 作用范围 应用场景
ServletContext 服务器启动 服务器正常关闭/项目从服务器移除 整个项目 记录访问次数,聊天室
HttpSession 没有session 调 用request.getSession()方法 session过期(默认30分钟)/调用invalidate()方法/服务器异常关闭 会话(多次请求) 验证码校验, 保存用户登录状态
HttpServletRequest 来了请求 响应这个请求(或者请求已经接收了) 一次请求 servletA和jsp(servletB)之间数据传递(转发的时候存数据)

C:\Users\yp\.IntelliJIdea2017.2\system\tomcat\_sz61\work\Catalina\localhost 目录查看

  • 如果是正常关闭服务器,

​ 把session钝化到服务器磁盘上,再次启动,把磁盘上的文件活化到内存里面

​ Session钝化:把内存中的session序列化到硬盘上

​ Session活化:从硬盘上读取序列化的session到内存中

2.三个域对象怎么选择?

三个域对象怎么选择?

​ 一般情况下, 最小的可以解决就用最小的.

​ 但是需要根据情况(eg: 重定向, 多次请求, 会话范围, 用session; 如果是转发,一般选择request)

小结

  1. session的销毁
    • invalidate()
  2. session应用场景
    • 验证码校验
    • 保存用户的登录状态
  3. 选择
    • 一般情况下, 最小的可以解决就用最小的.
      • 转发 一般选择request
      • 重定向 一般选择session

一次性验证码校验

1.需求

cookie&session&jsp_第7张图片

​ 在网站登录的时候,生成一个验证码.登录的时候对验证码进行校验.

2.分析

2.1生成验证码

  1. 拷贝验证码的jar包
  2. 创建CodeServlet
//1.生成验证码
//2.响应给客户端(浏览器)

2.2校验验证码

cookie&session&jsp_第8张图片

3.实现

  • 登录页面
<center>
    <h1>用户登录h1>
    <form action="login" method="post">
        姓名:<input type="text" name="username"/><br/>
        密码:<input type="password" name="password"/><br/>
        验证码:<input type="text" name="code"/><br/>
        <img src="code" onclick="changeImg(this)"/><br/>
        <input type="submit" value="登录"/>
    form>
center>
<script>
    function changeImg(obj) {
      
        //obj.setAttribute("src","code");
        //带参数没有实际的含义, 目的就是忽悠浏览器 路径不一样不要读取缓存
        obj.src = "code?a="+new Date().getMilliseconds();
        
    }
    
script>

  • CodeServlet
@WebServlet("/code")
public class CodeServlet extends HttpServlet {
     

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
        //1.生成验证码 int width 宽度, int height 高度, int codeCount 验证码的个数, int lineCount 干扰线的条数
        ValidateCode validateCode = new ValidateCode(200, 50, 4, 100);


        //2.生成的验证码存到session
        String code = validateCode.getCode();
        System.out.println("生成的验证码:" + code);
        request.getSession().setAttribute("code",code);


        //3.响应给客户端(浏览器)
        validateCode.write(response.getOutputStream());
    }

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

  • LoginServlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
     

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

            //0.处理乱码
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");

            //***************验证码的校验****************
            //1.获得用户输入的验证码
            String userCode = request.getParameter("code");
            //2.从session获得程序生成的验证码
            String sessionCode = (String) request.getSession().getAttribute("code");
            //3.比较, 判断是否一致
            if(!userCode.equals(sessionCode)){
     
                response.getWriter().print("验证码输入有误");
                return;
            }

            //******************************************

            //1.获得用户名和密码
            String username = request.getParameter("username");
            String password = request.getParameter("password");

            //2.使用DBUtils根据用户名和密码查询数据库 封装成User对象
            QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
            String sql = "SELECT * FROM user WHERE username = ? AND password  =?";
            User user = queryRunner.query(sql, new BeanHandler<User>(User.class), username, password);
            //3.判断是否登录成功(判断User是否为null)
            if (user != null){
     
                //3.1 user!= null 响应登录成功
                //把user保存到session里面
                request.getSession().setAttribute("user",user);

                //重定向到首页
                response.sendRedirect(request.getContextPath()+"/index.html");


            }else{
     
                //3.2 user== null 响应登录失败
                response.getWriter().print("登录失败!");
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            response.getWriter().print("登录失败!");
        }
    }

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

4.小结

  1. 需要在CodeServlet 把生成的验证码存到session里面

    • 不能存到ServletContext, 就共享验证码了
    • 不能存到request, 根本不能用
  2. 思路

    • CodeServlet: 生成验证码存到Session
    • LoginServlet:
      • 获得用户输入的验证码
      • 获得session里面存的验证码
      • 比较是否一致

第四章_JSP入门

4.1 什么是JSP

​ Java server page(java服务器页面). 【JSP本质就是Servlet

​ 它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。

JSP=html(js,css)+java+jsp特有的内容

4.2.JSP产生的原因

需求: 我们要向页面动态输出一个表格. 发现特别的繁琐

servlet在展示页面的时候,相当的繁琐。sun公司为了解决这个问题,参照asp开发了一套动态网页技术jsp。

4.3 JSP执行原理

C:\Users\yp.IntelliJIdea2017.2\system\tomcat_sz61\work\Catalina\localhost

JSP会翻译(通过默认的JspServlet,JSP引擎)成Servlet(.java),Servlet编译成class文件

​ JSP执行流程

​ 第一次访问的xxx.jsp时候,服务器收到请求,JspServlet会去查找对应的jsp文件

​ 找到之后,服务器会将这个jsp文件转换成java文件(Servlet)

​ 服务器编译java文件,生成class文件

​ 服务器运行class文件,生成动态的内容

​ 服务器收到内容之后,返回给浏览器

cookie&session&jsp_第9张图片

小结

  1. JSP: java 服务器 页面, sun公司定义的动态资源, 本质就是Servlet
  2. JSP产生的原因: Servlet在动态展示很麻烦, jsp展示方便一点

JSP基本语法

1.JSP脚本

我们可以通过JSP脚本在JSP页面上编写Java代码. 一共有三种方式:

类型 翻译成Servlet对应的部分 注意
<%…%>:Java程序片段 翻译成Service()方法里面的内容, 局部的
<%=…%>:输出表达式 翻译成Service()方法里面的内容,相当于调用out.print() 输出表达式不能以;结尾
<%!..%>:声明成员变量 翻译成Servlet类里面的内容
  • eg
 <%
		for(int i = 0; i < 10;i++){
			out.print("i="+i);
			%>
			
<% } %>

2.JSP注释

注释类型
HTML注释
JAVA注释 //; /* */
JSP注释; <%–注释内容–%>

注释快捷键:Ctrl+Shift+/

小结

  1. 脚本
    • <%%> 翻译成了service()方法里面的局部内容
    • <%=%> 输出, 翻译成了service()方法里面的out.print()
    • <%!%> 翻译成了servlet类里面的全局内容
  2. 注释
    • 注释快捷键:Ctrl+Shift+/

记住用户名案例

1.需求

cookie&session&jsp_第10张图片

2.分析

  1. 在LoginServlet里面, 如果用户登录成功:

    ​ //判断用户是否勾选了记住用户名

    ​ //勾选了, 把用户名存到Cookie

  2. 在login.jsp页面 从cookie取出展示

3.实现

  • LoginServlet
package com.itheima.web;

import com.itheima.bean.User;
import com.itheima.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;

/**
 * @Description:
 * @Author: yp
 */
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
     

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

            //0.处理乱码
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");

            //***************验证码的校验****************
            //1.获得用户输入的验证码
            String userCode = request.getParameter("code");
            //2.从session获得程序生成的验证码
            String sessionCode = (String) request.getSession().getAttribute("code");
            //3.比较, 判断是否一致
            if(!userCode.equals(sessionCode)){
     
                response.getWriter().print("验证码输入有误");
                return;
            }

            //******************************************

            //1.获得用户名和密码
            String username = request.getParameter("username");
            String password = request.getParameter("password");

            //2.使用DBUtils根据用户名和密码查询数据库 封装成User对象
            QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
            String sql = "SELECT * FROM user WHERE username = ? AND password  =?";
            User user = queryRunner.query(sql, new BeanHandler<User>(User.class), username, password);
            //3.判断是否登录成功(判断User是否为null)
            if (user != null){
     
                //3.1 user!= null 响应登录成功
                //****************记住用户名*********************
                //判断用户是否勾选了记住用户名
                String rem = request.getParameter("rem");
                if(rem != null && "ok".equals(rem)){
     
                    //勾选了, 把用户名存到Cookie
                    Cookie cookie = new Cookie("username", username);
                    cookie.setMaxAge(60*60*24*7);
                    cookie.setPath(request.getContextPath());
                    response.addCookie(cookie);
                }else {
     
                    //没有勾选 删除cookie
                    Cookie cookie = new Cookie("username", "");
                    cookie.setMaxAge(0);
                    cookie.setPath(request.getContextPath());
                    response.addCookie(cookie);
                }
                //***********************************************

                //把user保存到session里面
                request.getSession().setAttribute("user",user);
                //重定向到首页
                response.sendRedirect(request.getContextPath()+"/index.html");


            }else{
     
                //3.2 user== null 响应登录失败
                response.getWriter().print("登录失败!");
            }
        } catch (Exception e) {
     
            e.printStackTrace();
            response.getWriter().print("登录失败!");
        }
    }

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


  • login.jsp

cookie&session&jsp_第11张图片

小结

  1. 用户勾选了记住用户名,我们把用户名存到Cookie里面
  2. 在login.jsp里面 从cookie取出用户名展示

你可能感兴趣的:(session,cookie,jsp)