Servlet 的生命周期,什么是cookie,Session的详细解析,servletContext对象的详细解析

416 阅读7分钟

Servlet 的生命周期,什么是cookie,session对象的使用

复习一下:

URL:统一资源标识符,用来表述服务器中定位一个资源,资源在web项目中的路径(/project/source)

转发:服务器行为

重定向: 客户端行为

重定向没有作用域,两次跳转之间数据会丢失

一、Servlet声明周期(四个阶段)

  1. 实例化

当用户第一次访问servlet时,由容器调用Servlet的构造函数创建具体Servlet对象,也可以在容器启动后立即创建实例。使用如下代码可以设置Servlet是否在服务器启动时就创建了

  • 注意:只执行一次
  1. 初始化

在初始化阶段,init()方法会被调用,这个犯法在javax.servlet接口中定义,方法以一个servletConfig类型的对象作为参数

  • 注意:init()方法只执行一次
  1. 服务

当客户端有一个请求时,容器就会将请求servletRequest与响应servletresponse对象转给servlet,以参数的形式传给servlet方法

  • 注意:此方法会执行多次
  1. 销毁

当servlet 容器停止或者重启都会引起销毁servlet对象,并表用destroy方法

  • destroy方法执行一次

servlet生命周期.png

二、Servlet特性

servlet在访问之后,会执行实例化操作,创建一个Servlet对象。而我们Tomcat容器可以同时多个线程并发访可同一个servlet,如果在方法中对成员变量做修改操作,就会有线程安全的问题。

2.1 线程安全问题

Servlet在访问之后,会执行实例化操作,创建一个Servlet对象。而我们Tomcat容器可以同时多个线程并发访问同一个Servlet,如果在方法中对成员变量做修改操作,就会有线程安全的问题。

解决办法:

  • 使用synchronized

将存在线程安全问题的代码放到同步代码块中

  • 实现SingleThreadModel接口

servlet实现SingleThreadModel接口后,每个线程都会创建servlet实例,这样每个客户端请求就不存在共享资源的问题,但是servlet响应客户端请求的效率太低,所以已经淘汰。

  • 尽可能的使用局部变量,避免出现线程安全问题

2.2 状态管理

问题

  • HTTP协议是无状态的,不能保存每次提交的信息
  • 如果用户发来一个新的请求,服务器无法知道它是否与上次的请求有联系。
  • 对于那些需要多次提交数据才能完成的web操作,比如登录来说,就成问题了。

概念

将浏览器与wep服务器之间多次交互当作一个整体来处理,并且将多次交互所涉及的数据(即状态)保存下来。

状态管理分类

  • 客户端状态管理技术:将状态保存在客户端。代表性的是cookie技术。
  • 服务器状态管理技术:将状态保存在服务器端。代表性的是session技术((服务器传递sessionID时需要使用cookie的方式)和application

什么是cookie

  • Cookie是在浏览器访问web服务器的某个资源时,由web服务器在HTTP响应消息头中附带传送给浏览器的—小段数据。
  • 一旦web浏览器保存了某个Cookie,那么它在以后每次访问该web服务器时,都应在HTTP请求头中将这个Cookie回传给web服务器。
  • 一个Cookie主要由标识该信息的名称(name)和值(value)组成,键值对的形式。

cookie的优点

可配置到期规则。 简单性:Cookie是一种基于文本的轻量结构,包含简单的键值对。 数据持久性:Cookie默认在过期之前是可以一直存在客户端浏览器上的。

cookie缺点

大小受到限制:大多数浏览器对Cookie的大小有4K、8K字节的限制。 用户配置为禁用:有些用户禁用了浏览器或客户端设备接收Cookie的能力,因此限制了这一功能。、 潜在的安全风险:Cookie可能会被篡改。会对安全性造成潜在风险或者导致依赖于Cookie的应用程序失败。

三、session对象(重点)

3.1 session概述

  • Session用于记录用户的状态。Session指的是在一段时间内,单个客户端与Web服务器的一连串相关的交互过程。在一个
  • Session中,客户可能会多次请求访问同一个资源,也有可能请求访问各种不同的服务器资源。

3.2 session原理

  • 服务器会为每一次会话分配一个session对象
  • 同一个浏览器发起的多次请求,同属于一次会话(Session)
  • 首次使用到Session时,服务器会自动创建Session,并创建Cookie存储Sessionld发送回客户端

3.3 session的使用

  • Session作用域:拥有存储数据的空间,作用范围是一次会话有效
  • 一次会话是使用同一浏览器发送的多次请求。一旦浏览器关闭,则结束会话。
  • 可以将数据存入Session中,在一次会话的任意位置进行获取
  • 可传递任何数据(基本数据类型、对象、集合、数组)

注意:session是由服务端创建的

3.4 获取session

session是由服务端创建的,通过request对象获取

HhttpServlet  session = request.getSession();
System. out. println("Id: "+session. getId()); //唯一标记,

3.5 session保存数据

setAttribute(属性名,Object) 数据保存在session中

session.setAttribute("key",value); 以键值对的形式存储在session作用域中

3.6 session 的移除

之前也说过session的移除

  1. 服务器关闭了 session被自动移除
  2. 到了时间比如一般是30分钟没有操作session也会被移除
  3. 使用invalidate() 方法手动移除session

注意:使用removeAttribute("key"),并不能删除session,值还在,只是没有起到相应的作用了

3.7 session与request 的区别

  • request是一次请求有效,请求改变,则request改变
  • session是一次会话有效,浏览器改变,则session改变

3.8 session的生命周期

  • 开始: 第一次使用session的请求产生,创建session

  • 结束:

    1. 浏览器关闭
    2. sesison超时
    3. 手工销毁 使用 session.invalidate();方法
package com.zking.sessionServlet;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
​
@WebServlet("/sessions")
public class Sessions extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        System.out.println(session.getId());
    }
}

结果:

//浏览器关闭结果
E53B3B916D0F07A6E7A808E606BF1F4A
536D01626278E1835B34FCEAB5738663
​
//关闭与重启服务器结果
E53B3B916D0F07A6E7A808E606BF1F4A
2A3DE307F69EA6939D27542699E7E8C0

3.9 浏览器禁用cookie的解决方案

  • 浏览器禁用cookie的后果

服务器在默认情况下,会使用Cookie的方式将sessionID发送给浏览器,如果用户禁止Cookie,则sessionID不会被浏览器保存,此时,服务器可以使用如URL重写这样的方式来发送sessionlD。

  • 重写URL

response.encodeRedirectURL(String url)生成重写的URL。

        HttpSession session = req.getSession();
        String  newUrl = resp.encodeRedirectURL("/WebProject_war_exploded/cs");
        resp.sendRedirect(newUrl);

四、servletContext对象(重点)

4.1servletContext概述

  • 全局对象,也拥有作用域,对应一个Tomcat中的Web应用
  • 当Web服务器启动时,会为每一个Web应用程序创建一块共享的存储区域
  • (ServletContext).ServletContext在Web服务器启动时创建,服务器关闭时销毁。

4.2获取servletContext对象

  • GenericServlet提供了getServletContext()方法。(推荐)this.getServletContext();
  • HttpServletRequest提供了getServletContext()方法。(推荐)
  • HttpSession提供了getServletContext()方法。
package com.zking.controller;
​
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
​
@WebServlet("/path_")
public class ServletContextTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取servletContext的三种方法
//        方法1 : 通过GenericServlet中的this.getServletContext()方法  (推荐)
         ServletContext ServletContext1 =  this.getServletContext();
//        方法2: 通过HttpServlet中的getServletContext()方法 (推荐)
         ServletContext ServletContext2 = req.getServletContext();
//         方法3: 通过HttpSession方法  
        HttpSession session = req.getSession();
        ServletContext ServletContext3 = session.getServletContext();
​
        System.out.println(ServletContext1);
        System.out.println(ServletContext2);
        System.out.println(ServletContext3);
​
    }
}

运行结果:

三种获取ServletContext的方法.png 4.3servletContext的作用

  1. 获取项目真实路径
String realpath=servletContext.getRealPath("/”);

结果:

D:\桌面\日期\阶段二\第三周\seven\out\artifacts\seven_war_exploded\
  1. 获取项目上下文路径
String path=ServletContext1.getContextPath();

结果:

/seven_war_exploded

4.4 ServletContext是一个全局容器

  • ServletContext拥有作用域,可以存储数据到全局容器中
  • 存储数据:servletContext.setAttribute("name",value);
  • 获取数据:servletContext.getAttribute("name");
  • 移除数据:servletContext.removeAttribute("name");

4.5servletContext特点

  • 唯一性:一个应用对应一个ServletContext。
  • 生命周期:只要容器不关闭或者应用不卸载,ServletContext就一直存在。

五、servletContext应用场景

应用场景为:servletContext统计项目的访问次数,很实用!

因为文章有点长,所以就放到下一篇进行展示与总结