Servlet 的生命周期,什么是cookie,session对象的使用
复习一下:
URL:统一资源标识符,用来表述服务器中定位一个资源,资源在web项目中的路径(/project/source)
转发:服务器行为
重定向: 客户端行为
重定向没有作用域,两次跳转之间数据会丢失
一、Servlet声明周期(四个阶段)
- 实例化
当用户第一次访问servlet时,由容器调用Servlet的构造函数创建具体Servlet对象,也可以在容器启动后立即创建实例。使用如下代码可以设置Servlet是否在服务器启动时就创建了
- 注意:只执行一次
- 初始化
在初始化阶段,init()方法会被调用,这个犯法在javax.servlet接口中定义,方法以一个servletConfig类型的对象作为参数
- 注意:init()方法只执行一次
- 服务
当客户端有一个请求时,容器就会将请求servletRequest与响应servletresponse对象转给servlet,以参数的形式传给servlet方法
- 注意:此方法会执行多次
- 销毁
当servlet 容器停止或者重启都会引起销毁servlet对象,并表用destroy方法
- destroy方法执行一次
二、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的移除
- 服务器关闭了 session被自动移除
- 到了时间比如一般是30分钟没有操作session也会被移除
- 使用invalidate() 方法手动移除session
注意:使用removeAttribute("key"),并不能删除session,值还在,只是没有起到相应的作用了
3.7 session与request 的区别
- request是一次请求有效,请求改变,则request改变
- session是一次会话有效,浏览器改变,则session改变
3.8 session的生命周期
开始: 第一次使用session的请求产生,创建session
结束:
- 浏览器关闭
- sesison超时
- 手工销毁 使用 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);
}
}
运行结果:
4.3servletContext的作用
- 获取项目真实路径
String realpath=servletContext.getRealPath("/”);
结果:
D:\桌面\日期\阶段二\第三周\seven\out\artifacts\seven_war_exploded\
- 获取项目上下文路径
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统计项目的访问次数,很实用!
因为文章有点长,所以就放到下一篇进行展示与总结