云计算百科
云计算领域专业知识百科平台

Servlet 中的三个域对象

Servlet 中的三个域对象

Servlet 中的“域对象”指的是可以在一定范围内共享数据的对象。Java Web 中通常说的三大域是 request、session、application,它们的作用范围从小到大排列。JSP 中还有一个 pageContext(页面域),范围最小,通常不计入“Servlet 三大域”。

一、三大域总览

域对象类型作用范围生命周期
request HttpServletRequest 一次请求 请求开始到响应结束
session HttpSession 一次会话 会话创建到失效(浏览器关闭或超时)
application ServletContext 整个 Web 应用 服务器启动到关闭

作用范围:request < session < application。

二、request 域

本质:HttpServletRequest 对象。每次 HTTP 请求,容器都会创建一个新的 request 对象。

作用范围:仅当前这一次请求。请求结束,request 对象销毁,域中的数据也随之消失。

常用方法:

request.setAttribute("key", value); // 存数据
Object value = request.getAttribute("key"); // 取数据
request.removeAttribute("key"); // 删数据

典型场景:

  • 请求转发时,在 Servlet 中存数据,JSP 或另一个 Servlet 中取数据。
  • 一次请求内的错误信息、提示信息传递。

// Servlet 中
request.setAttribute("msg", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);

// login.jsp 中
${msg}

请求转发(forward)是同一个 request,数据可以共享;重定向(redirect)是新的请求,request 域数据会丢失。

在 Spring MVC 中的对应:

  • Controller 方法参数 HttpServletRequest request
  • Model、ModelMap、ModelAndView 底层也是把数据放入 request 域
  • @RequestAttribute 读取 request 域

@GetMapping("/login")
public String login(Model model) {
model.addAttribute("msg", "用户名或密码错误");
return "login"; // 数据放入 request 域
}

三、session 域

本质:HttpSession 对象。代表一次用户会话,从用户第一次访问到会话失效。

作用范围:同一个会话内的所有请求共享。不同用户、不同浏览器对应不同的 session。

生命周期:

  • 创建:第一次调用 request.getSession() 时创建。
  • 销毁:调用 session.invalidate()、超过 maxInactiveInterval 时间未活动、浏览器关闭(会话 Cookie 失效)。

常用方法:

HttpSession session = request.getSession(); // 获取或创建
session.setAttribute("user", user); // 存数据
Object user = session.getAttribute("user"); // 取数据
session.removeAttribute("user"); // 删数据
session.invalidate(); // 销毁会话

典型场景:

  • 保存登录用户信息。
  • 保存购物车。
  • 保存验证码。

// 登录成功后
User user = userService.login(username, password);
request.getSession().setAttribute("loginUser", user);

// 其他请求中判断是否登录
User user = (User) request.getSession().getAttribute("loginUser");
if (user == null) {
response.sendRedirect("/login");
}

在 Spring MVC 中的对应:

  • Controller 方法参数 HttpSession session
  • @SessionAttribute 读取 session 域
  • @SessionAttributes 把 Model 中的数据暂存到 session

@GetMapping("/profile")
public String profile(HttpSession session) {
User user = (User) session.getAttribute("loginUser");
return "profile";
}

四、application 域

本质:ServletContext 对象。代表整个 Web 应用,服务器启动时创建,服务器关闭时销毁。

作用范围:整个应用内所有用户、所有请求共享。一个应用只有一个 ServletContext。

常用方法:

ServletContext context = request.getServletContext();
context.setAttribute("count", 100); // 存数据
Object count = context.getAttribute("count"); // 取数据
context.removeAttribute("count"); // 删数据

典型场景:

  • 全局配置信息。
  • 全局计数器(如网站访问量)。
  • 应用启动时加载的共享资源。

// 全局访问量
ServletContext context = request.getServletContext();
Integer count = (Integer) context.getAttribute("visitCount");
if (count == null) {
count = 1;
} else {
count++;
}
context.setAttribute("visitCount", count);

注意:application 域是全局共享的,多线程并发访问时需要注意线程安全。计数器场景应该用 AtomicInteger。

在 Spring MVC 中的对应:

  • Controller 方法参数 ServletContext
  • @ApplicationScope(Spring 5.3+)读取 application 域
  • Spring 的 ApplicationContext 和 ServletContext 不是同一个东西,但可以通过 WebApplicationContextUtils 获取

@GetMapping("/count")
public String count(ServletContext context) {
AtomicInteger count = (AtomicInteger) context.getAttribute("visitCount");
count.incrementAndGet();
return "count";
}

五、pageContext 域(补充)

JSP 中还有 pageContext,作用范围仅当前 JSP 页面,相当于当前 JSP 的局部变量。它不属于 Servlet 三大域,但在 JSP 中常被提及。

<% pageContext.setAttribute("name", "张三"); %>
<%= pageContext.getAttribute("name") %>

范围:pageContext < request < session < application。

六、三大域对比

对比维度requestsessionapplication
类型 HttpServletRequest HttpSession ServletContext
范围 一次请求 一次会话 整个应用
创建时机 每次请求 第一次 getSession() 应用启动
销毁时机 响应结束 会话失效 应用关闭
用户隔离 天然隔离 每个用户独立 所有用户共享
线程安全 单请求内安全 同一用户并发需注意 多用户并发需注意
典型数据 请求级提示、转发数据 登录用户、购物车 全局配置、访问计数

七、如何选择域对象

数据需要存活多久选择
只在当前请求内有效 request
在当前用户会话内有效 session
所有用户、整个应用内有效 application

一个简单的判断方法:数据是给谁看的,就放到对应的域。

  • 只给当前请求的页面看 → request
  • 只给当前登录用户看 → session
  • 给所有用户看 → application

八、在 Spring MVC 中统一理解

Spring MVC 底层仍然基于 Servlet,三大域在 Spring MVC 中依然存在,只是有了更上层的封装。

Servlet 域Spring MVC 对应
request HttpServletRequest、Model、ModelMap、ModelAndView、@RequestAttribute
session HttpSession、@SessionAttribute、@SessionAttributes
application ServletContext、@ApplicationScope

Controller 方法中可以直接声明这些参数,Spring 会自动注入:

@GetMapping("/demo")
public String demo(HttpServletRequest request,
HttpSession session,
ServletContext context) {
request.setAttribute("req", "请求域");
session.setAttribute("sess", "会话域");
context.setAttribute("app", "应用域");
return "demo";
}

九、总结

域对象一句话说明常用场景
request 一次请求内共享数据 请求转发、错误提示
session 一次会话内共享数据 登录用户、购物车、验证码
application 整个应用内共享数据 全局配置、访问计数

三大域的核心区别在于作用范围和生命周期。request 最小,一次请求即失效;session 按用户隔离,会话结束失效;application 全局共享,应用关闭才失效。选择哪个域,取决于数据需要存活多久、需要给谁看。理解这三个域,也就理解了 Java Web 中数据传递的基本方式,Spring MVC 的 Model、@SessionAttribute 等封装,底层都建立在这三个域之上。

赞(0)
未经允许不得转载:网硕互联帮助中心 » Servlet 中的三个域对象
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!