会话技术

会话技术

购物车案例引出会话对象

在这里插入图片描述

Cookie技术

在客户端保存的数据,数据产生是在服务器

在浏览器中Cookie是以文本的形式保存数据

什么是cookie

HTTP Cookie(也叫 Web Cookie或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。

Cookie主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

服务器向浏览器发送Cookie

  • Cookie对象,直接new Cookie(String key,String value)
  • 将Cookie数据保存到客户端 response对象方法 addCookie()
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /**
     *  创建Cookie对象,构造方法传递键值对
     *  响应对象response,将Cookie响应回浏览器
     */
    Cookie cookie = new Cookie("heima","java");
    response.addCookie(cookie);
}

获取浏览器携带的Cookie

浏览器在访问服务器的时候携带Cookie数据,服务器端使用request对象获取Cookie

Cookie数据,会放在请求头

  • request对象方法 Cookie[] getCookies() 获取多个Cookie,返回的是Cookie对象数组
  • Cookie对象方法 getName()获取Cookie的键, getValue()获取Cookie中的值
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /**
     *  获取客户端浏览器携带的Cookie数据
     *  request对象方法 getCookies()
     */
    Cookie[] cookies =  request.getCookies();
    for (Cookie cookie : cookies){
        //遍历数组,取出的是数组中的每个Cookie对象
        //取出Cookie中的键
        String key = cookie.getName();
        //取出Cookie中的值
        String value = cookie.getValue();
        System.out.println(key+"==="+value);
    }
}

Cookie中使用中文问题(扩展)

Cookie数据,值可以使用中文,建议不要使用中文

在Cookie使用中文,Tomcat低版本不支持,从Tomcat8开始支持中文

你好-> %AE%3A%CD

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String name = "哈哈";
    name = URLEncoder.encode(name,"utf-8");
    System.out.println(name);

    Cookie cookie = new Cookie("haha",name);
    response.addCookie(cookie);

    Cookie[] cookies = request.getCookies();
    for (Cookie cookie2: cookies){
        String value = URLDecoder.decode( cookie2.getValue(),"utf-8");
        System.out.println(cookie2.getName()+"=="+value);
    }
}

Cookie的携带路径

浏览器访问服务器,每次都会携带Cookie进行访问吗

Cookie数据放在请求头,每次浏览器请求服务器,都会携带吗

  • 结论: 浏览器携带Cookie,在Cookie产生的路径下
  • Cookie的产生路径: /abc下产生的
  • 浏览器访问/abc下的任意资源,携带Cookie
  • 访问不是/abc下的资源,不会携带Cookie
  • 需求: 只要访问WEB应用下的任意资源都携带Cookie
  • Cookie对象方法 setPath()设置携带路径
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = new Cookie("heima","java");
    //设置Cookie的携带路径,WEB应用名称,不要写死的
    cookie.setPath( request.getContextPath());
    response.addCookie(cookie);
}

Cookie的生存时间

浏览器中Cookie是有生存时间,默认是当前会话.浏览器关闭,会话结束

设置生存时间,Cookie对象方法 setMaxAge(int 秒)

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie cookie = new Cookie("heima","java");
    cookie.setPath(request.getContextPath());
    //设置生存时间
    cookie.setMaxAge(60);
    response.addCookie(cookie);
}

记录上一次的访问时间

在这里插入图片描述

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=utf-8");
    //获取客户端携带的Cookie
    Cookie[] cookies = request.getCookies();
    //获取当前时间,时间格式中间不能有空,否则出错
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
    String time = sdf.format(new Date());

    //判断数组
    if (cookies==null){
        //没有数据,第一次访问
        response.getWriter().write("欢迎第一次访问");
        //当前时间,存储到Cookie中
        Cookie cookie = new Cookie("time",time);
        cookie.setMaxAge(60*10);
        cookie.setPath(request.getContextPath());
        response.addCookie(cookie);
    }else {
        //有数据,获取cookie中存储时间
        for(Cookie cookie :cookies){
            String key = cookie.getName();
            String value = cookie.getValue();
            response.getWriter().write("上次访问时间是:"+value);
            Cookie cookie2 = new Cookie("time",time);
            cookie2.setMaxAge(60*10);
            cookie2.setPath(request.getContextPath());
            response.addCookie(cookie2);
        }
    }
}

Session域对象

什么是session

Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。

HttpSession接口,session对象是接口的实现类,实现类对象tomcat引擎创建

方法 request.getSession()获取session对象

作用域 : 一次会话有效,浏览器不关闭

  • 域对象存储数据: setAttribute(String key,String value)
  • 取出域对象数据: Object getAttribute(String key)
  • 移除域对象数据: removeAttribute(String key)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /**
     *  获取session对象
     *  域中存储和取出数据
     */
    HttpSession session = request.getSession();
    session.setAttribute("heima","java");
    Object value = session.getAttribute("heima");
    System.out.println("session1="+value);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Object value = request.getSession().getAttribute("heima");
    System.out.println("session2="+value);
}

持久化Session对象

获取session对象id,存取到cookie里,响应到浏览器,注意键一定是JSESSIONID,关闭浏览器后,再此打开浏览器,会拿着存取的cookie访问。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession();
    session.setAttribute("testSession","testSession");
    //session方法,getId() 获取session对象的唯一编码,返回String
    String id = session.getId();
    System.out.println(id);
    //id值,存储到Cookie中
    Cookie cookie = new Cookie("JSESSIONID",id);
    cookie.setMaxAge(60*10);
    cookie.setPath(request.getContextPath());
    response.addCookie(cookie);
}

session生命周期

在这里插入图片描述

session域对象生命时候生,什么时候销毁

  • session对象什么时候创建
    • request.getSession()方法,Cookie中id和服务器的id匹配不上就创建
  • session对什么时候销毁
    • 默认30分钟销毁, tomcat全局配置文件web.xml
    • 调用方法session.invalidate();
    • 关闭 (非正常关闭) 服务器
    • 正常关闭的情况下会序列化硬盘里,再打开的时候会反序列化回来

如何清空Cookie

  • 覆盖的方式情况
    • 保证同名键
    • 保证相同的携带路径
    • setMaxAge(0)

Cookie 和 Session 有什么不同?

  • 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
  • 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。

Cookie和Session关联

说起来为什么需要 Cookie ,这就需要从浏览器开始说起,我们都知道浏览器是没有状态的(HTTP 协议无状态),这意味着浏览器并不知道是张三还是李四在和服务端打交道。这个时候就需要有一个机制来告诉服务端,本次操作用户是否登录,是哪个用户在执行的操作,那这套机制的实现就需要 Cookie 和 Session 的配合。

那么 Cookie 和 Session 是如何配合的呢?我画了一张图大家可以先了解下。
在这里插入图片描述
用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session ,请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名。

当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

验证码案例

验证码本质是图片,图片里面是随机生成的字符串

字符串存储在Session域对象

客户端浏览器填写验证码(String),提交服务器Servlet

取出验证码,取出session域中的验证码, 比较
codeServlet

@WebServlet(urlPatterns = "/code")
public class CodeServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //  创建画布
       int width = 120;
       int height = 40;
       BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
       //  获得画笔
       Graphics g = bufferedImage.getGraphics();
       //  填充背景颜色
       g.setColor(Color.white);
       g.fillRect(0, 0, width, height);
       //  绘制边框
       g.setColor(Color.red);
       g.drawRect(0, 0, width - 1, height - 1);
       //  生成随机字符
       //  准备数据
       String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
       //  准备随机对象
       Random r = new Random();
       //  声明一个变量 保存验证码
       String code = "";
       //  书写4个随机字符
       for (int i = 0; i < 4; i++) {
           //  设置字体
           g.setFont(new Font("宋体", Font.BOLD, 28));
           //  设置随机颜色
           g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));

           String str = data.charAt(r.nextInt(data.length())) + "";
           g.drawString(str, 10 + i * 28, 30);

           //  将新的字符 保存到验证码中
           code = code + str;
       }
       //  绘制干扰线
       for (int i = 0; i < 6; i++) {
           //  设置随机颜色
           g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));

           g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
       }

       //  将验证码 打印到控制台
       System.out.println(code);

       //  将验证码放到session中
       request.getSession().setAttribute("code_session", code);

       //  将画布显示在浏览器中
       ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
   }

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

}

check

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=utf-8");
    //获取页面填写验证码
    String code = request.getParameter("code");
    //session域对象取出存储验证码
    String code_session = (String) request.getSession().getAttribute("code_session");
    if(code_session.equalsIgnoreCase(code)){
        response.getWriter().write("验证码正确");
    }else {
        response.getWriter().write("验证码错误");

    }
}

前端页面

<form method="post" action="/WEB05/check">
    <input type="text" name="code">
    <img src="/WEB05/code" onclick="fnChange()" id="code">
    <input type="submit">

  </form>
<script type="text/javascript">
    function fnChange() {
        /*
         *  页面打开的时候,请求服务器资源/WEB03/code
         *  点击图片js函数中,发了请求/WEB03/code
         *
         *  请求的资源没有变化,服务器端程序也没有变化
         *  浏览器拿缓存吧
         *
         *  每次请求不一样就行,添加参数
         */
        //点击图片,修改src的属性值
        var code = document.getElementById("code");
        var date = new Date().getTime();
        code.src="/WEB05/code?a="+date;
    }
</script>

JSP技术

JSP称为Java的动态服务器端网页技术,(Java Server Page).

Java程序直接嵌入到了HTML中,页面称为jsp页面

Java嵌入HTML方式 <% %> <%= %> <%! %>

JSP页面的执行原理

jsp页面,执行的时候被转成.java文件,编译为.class

转换后目录:

C:\Users\shisong.IntelliJIdea2017.3\system\tomcat\Tomcat_8_5_32_heima331\work\Catalina\localhost\WEB05\org\apache\jsp\jsp

C:\apache-tomcat-8.5.32\work\Catalina\localhost\WEB05\org\apache\jsp\jsp

JSP本质就是Servlet

在这里插入图片描述

JSP中的注释

  • JSP中存在,翻译后的.java存在,浏览器中存在
  • <% // /* Java自己注释%> JSP中存在,翻译后的.java存在,浏览器没有

  • <%-- JSP特有注释 --%> 只在JSP源代码中出现

JSP九大内置对象

  • request
  • response
  • ServletContext对象,在JSP写对象,只能写 application
  • ServletConfig对象,在JSP写对象,只能写config
  • session
  • out
  • page
  • pageContext 最小域对象,作用范围是当前页面
  • exception异常

JSP中存在,翻译后的.java存在,浏览器中存在

  • <% // /* Java自己注释%> JSP中存在,翻译后的.java存在,浏览器没有

  • <%-- JSP特有注释 --%> 只在JSP源代码中出现

JSP九大内置对象

  • request
  • response
  • ServletContext对象,在JSP写对象,只能写 application
  • ServletConfig对象,在JSP写对象,只能写config
  • session
  • out
  • page
  • pageContext 最小域对象,作用范围是当前页面
  • exception异常
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值