java web开发中servlet三大作用域对象为request、session和application(ServletContext)。
request表示一个请求,只要发出一个请求就会创建一个request。
作用域:仅在当前请求中有效。
简单说:session是一个时间段,表示客户端与服务器交互的一个时间段。
服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有Servlet共享。
作用域:用户从打开浏览器会话开始,直到关闭本次会话所有浏览器窗口,并且超时,会话才会结束。一次会话期间只会创建一个session对象。
获取方式:
HttpSession session = request.getSession();
session实现的内部原理如下:
当客户端访问服务器的某个资源时(静态资源除外,比如:html,css,js),服务器会创建一个名字叫JSESSIONID的会话编号,并且把它写入到客户端浏览器的cookie中。以后客户端每次访问服务器的资源时,客户端都会携带这个JSESSIONID和服务器的JSESSIONID对比,如果相同说明是同一个会话。

所有的用户都可以取得这个信息,此信息在整个服务器中被保留。application属性范围值,只要设置一次,则所有的网页窗口都可以取得数据。
ServletContext在服务器启动时创建,在服务器关闭时销毁,一个javaweb应用只能创建一个ServletContext对象。所有客户端在访问服务器时共享同一个ServletContext对象。
获取方式:
ServletContext application= request.getServletContext();
//HelloServlet
package com.servlet;
import javax.servlet.ServletConfig;
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 java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Enumeration;
@WebServlet(value = "/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//保存在request
req.setAttribute("city","西安");
//保存在session
String sessionId = req.getSession().getId(); //获取当前会话ID。
req.getSession().setAttribute("sessionId",sessionId);
//保存在application
String date = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
req.getServletContext().setAttribute("date",date);
//通过请求重定向测试三个作用域。
resp.sendRedirect(req.getContextPath()+"/test");
}
}
//TestServlet
package com.servlet;
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 java.io.IOException;
@WebServlet(name = "TestServlet", value = "/test")
public class TestServlet extends HttpServlet {
public TestServlet() {
System.out.println("执行TestServlet的构造方法...");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String city=null;
String sessionId = null;
String date = null;
//获取request内保存的城市。
if(request.getAttribute("city")!=null) {
city = (String) request.getAttribute("city");
}
//因为使用了请求重定向,不是一次请求了,所有这里输出是null.
System.out.println("request内的city=" + city);
//获取session内保存的会话编号
if(request.getSession().getAttribute("sessionId")!=null){
sessionId = (String) request.getSession().getAttribute("sessionId");
}
System.out.println("session内的会话编号=" + sessionId);
//获取application内保存的日期
if(request.getServletContext().getAttribute("date")!=null){
date = (String) request.getServletContext().getAttribute("date");
}
System.out.println("application内的日期=" + date);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
启动tomcat后,分别使用两款不同的浏览器测试(比如:IE和Chrome),在地址输入测试地址: http://localhost:8080/helloservlet/hello
IE浏览器发出请求后,控制台输出内容如下:
request内的city=null
session内的会话编号=FD5F92FE84FC2EAED2D53E0E81E8678C
application内的日期=2020-04-08
Chrome浏览器发出请求后,控制台输出内容如下:
request内的city=null
session内的会话编号=825756DAC591D71BAE6C4292E3E9B004
application内的日期=2020-04-08
我们发现,不同的会话,有不同的会话ID。当然,这样测试还不足以说明application里保存的日期对象是所有用户所共享的。我们可以换一个思路,让Chrome浏览器,单独请求http://localhost:8080/helloservlet/test 控制台输出内容如下:
request内的city=null
session内的会话编号=null
application内的日期=2020-04-08
这样就很好的说明了application里保存的日期对象是被所有客户端所共享的。
request的一个作用是获取信息--通过用户提交的表单,查询字符串,cookie等获得信息 ,第二个作用是请求资源。比如:http://localhost:8080/myapp/hello, 表示请求hello这个资源。即便是下次请求相同的资源,也是不同的请求(这个道理好比,你去饭馆吃饭,点了两瓶相同的啤酒,也是发了两次不同的请求)。
session是表示客户端与服务器交互的一个时间段(这个道理好比,你去一家饭馆吃饭的时间段,从进入饭馆点菜到最后结账离开,这一段时间。),session是保存在服务器内存里面,是服务端用来保存一些数据(通常是标记状态的,当然也可以保存别的) 。session通常可以用来跟踪用户的动作,比如登录,退出等。
session可以跨越很多页面。而session的生命周期也是针对一个客户端,但是却是在别人设置的会话周期内(一般是20-30分钟),session里边的内容将一直存在,即便关闭了这个客户端浏览器 session也不一定会马上释放掉的。
简单来说:request是请求资源,而session是一个时间段。request的生命周期只在数据提交,提交以后即释放,session则是浏览器关闭并且超时后才释放。