属性是存在于3个Servlet API对象(ServletContext、HttpSession和HttpServletRequest)中的对象集。简单来说,我们可以认为它们是键值对的集合。
对于属性的作用域也有3个,即Context、Session和Request作用域,属性可以绑定到这三个作用域上。每个作用域都有它的优点和缺点。取决于具体的需求,我们会将一个属性存放到其中的一个作用域中。
用于存储、查询和删除这些属性的方法对于所有的作用域都是相同的。它们是:
Object getAttribute(String name);
void setAttribute(String name, Object value);
void removeAttribute(String name);
Enumeration getAttributeNames();
请求作用域
用于将属性存储到请求作用域中的类为ServletRequest。
绑定到请求作用域上的属性仅仅在同一个请求中可用。一旦请求完成,所有绑定到该请求上的属性都会被清空。因此对于该作用域中的属性,没有办法在不同的请求间共享。
因此,当你确信该属性不会由其他Servlet或同一的Servlet的不同请求使用时,可以使用该作用域。
会话作用域
用于将属性存储到会话作用域中的类为HttpSession。
绑定到会话作用域上的属性在同一会话中的所有Servlet操作期间都可用(当然它应该在同一个应用中)。
会话作用域中的属性是非线程安全的。因为会话作用域中的属性在会话期间对所有的Servlet操作都是可用的,因此出现两个不同的Servlet修改同一个会话属性是可能的。举例来说:
Servlet1.java
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("attr1", "1");
String attr1 = (String) session.getAttribute("attr1");
PrintWriter writer = resp.getWriter();
writer.print(attr1);
writer.close();
}
Servlet2.java
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
String attr1 = (String) session.getAttribute("attr1");
session.setAttribute("attr1", "3");
attr1 = (String) session.getAttribute("attr1");
PrintWriter writer = resp.getWriter();
writer.print(attr1);
writer.close();
}
打开浏览器让后在两个浏览器标签页里输入servlet1和servlet2的URL,然后查看下结果。在很少的情况下,你会看到servlet1的输出结果为3.你可能会很惊讶因为servlet1中将attr1的值设置为1.这个是可能发生的,因为会话作用域属性不是线程安全的。
现在,让我们看一下,该如何解决该问题呢。我们知道对于Servlet的请求,web容器会创建一个新线程。因此大部分开发者会尝试同步doGet方法来避免并发问题。确实,同步doGet方法将保证同时只有一个线程会进入doGet方法但是它仍然不能解决2个不同的Servlet同时更新会话作用域的属性。因此,最好的方法是同步HttpSession对象。修改后的代码如下:
Servlet1.java
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
String attr1 = "";
synchronized (session) {
session.setAttribute("attr1", "1");
attr1 = (String) session.getAttribute("attr1");
}
PrintWriter writer = resp.getWriter();
writer.print(attr1);
writer.close();
}
上述代码将保证在servlet1执行的时候不会有同步问题。无论执行多少次servlet1,输出总是1.
而同步doGet是一个非常大的错误。这将既不能解决该问题也不允许多用户同时访问该Servlet。
上下文作用域
用于将属性存储到上下文作用域的类是ServletContext。
绑定到该作用域的属性在整个应用期间都是可用的(从应用启动和运行后)。因此,要注意,不能绑定任何消耗内存的对象到该作用域上因为这些对象对垃圾回收是不可见的(不会被回收)。
同样,上下文作用域中的属性也是非线程安全的。因此要避免同步问题,我们需要同步ServletContext中存储的对象。
什么时候将属性存储在请求作用域、会话作用域和上下文作用域中?
请求作用域 | 会话作用域 | 上下文作用域 |
当我们需要使请求参数仅仅对当前请求有效时使用该作用域 | 参数需要在整个会话期间有效时使用该作用域 | 当我们需要存储对整个应用都有效的属性时,使用该作用域 |
请求参数被存放到该作用域中 | 登录信息和有状态的对象 | 像数据库链接、JNDI查询等资源 |
线程安全 | 非线程安全 | 非线程安全 |
分享到:
相关推荐
2. **request**作用域:比page作用域稍大,一个请求中的所有资源(如Servlet、JSP)都能访问在此作用域内设置的属性。这意味着,如果一个请求经过了多个Servlet或JSP,这些对象依然可用。`request.setAttribute()`...
此对象提供4个作用域层次的属性查询和修改能力,也提供转发请求到其他资源和包含其他资源的方法,该对象的方法都是抽象的。 4. Exception 对象(异常对象) Exception 对象是java.lang.Throwable类型,通过JSP页面...
jsp九大内置对象和四大作用域详解 jsp中的九大内置对象和四大作用域是jsp编程中非常重要的概念,它们提供了访问和操作服务器端资源的能力,帮助开发者快速构建动态Web应用程序。 一、request对象 request对象代表...
1. request 请求对象,类型 javax.servlet.ServletRequest,作用域 Request 2. response 响应对象,类型 javax.servlet.SrvletResponse,作用域 Page 3. pageContext 页面上下文对象,类型 javax.servlet.jsp....
【session 作用域】在Java Web开发中,session是一个至关重要的概念,它是HTTP协议无状态特性的补充,用于在客户端浏览器和服务器之间维持状态信息。简单来说,session就是服务器为每个用户浏览器创建的一个数据存储...
例如,`pageContext.getAttribute("attrName", PageContext.APPLICATION_SCOPE)`可以获取在application作用域内的属性。 7. **page**:当前JSP页面的实例,通常是一个实现了Servlet接口的类的实例。 8. **page...
1、说一说Servlet的生命周期?★★★★★ 答: servlet有良好的生存期的定义,包括加载和实例化、初始化、处理请求以及服务结束。...这实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域。
这个作用域只在基于Servlet的ApplicationContext中可用,适用于处理请求相关的数据。 4. **会话(Session)**:同样局限于Web应用,`scope="session"`表示每个HTTP会话都有一个Bean实例。它用于存储用户会话相关的...
其次,GlassFish2.x支持的是servlet2.5,而servlet2.5不支持Session Cookie的"HttpOnly"属性。不过使用Filter做一定的处理可以简单的实现HttpOnly属性。GlashFish3.0(支持servlet3.0)默认开启Session Cookie的...
如果用户名和密码匹配,Servlet会将用户信息保存在session作用域中,通常会设置一个session属性,例如`session.setAttribute("currentUser", user)`,以便后续页面可以访问这个已登录的用户。同时,Servlet会重定向...
在Servlet中,我们使用`request.getRequestDispatcher("/bbs.jsp").forward(request, response)`将控制权传递给`bbs.jsp`,这样,请求和响应对象会保持不变,JSP页面可以访问之前设置在请求作用域内的属性。...
同时,开发者也需要根据具体场景来决定合适的作用域,比如页面级的数据使用page作用域,而临时需要在一次请求中使用的数据使用request作用域。 此外,由于JSP的作用域是基于客户端和服务器端之间的交互模式设计的,...
16.5 访问作用域变量 16.6 访问bean的属性 16.7 访问集合 16.8 引用隐式对象 16.9 表达式语言中运算符的应用 16.10 表达式的条件求值 16.11 表达式语言其他功能概览 第ⅲ部分 支持技术 第17章 数据库...
1. request 请求对象:类型为 javax.servlet.ServletRequest,作用域为 Request 2. response 响应对象:类型为 javax.servlet.SrvletResponse,作用域为 Page 3. pageContext 页面上下文对象:类型为 javax.servlet....
EL(Expression Language)是JSP 2.0引入的一种轻量级表达式语言,用于从页面作用域中获取和设置对象属性。EL简化了在JSP中获取和使用JavaBean属性的过程,使页面更加简洁。 JSTL是一套标准的JSP标签库,提供了一...
3. **属性作用域**:不同范围的属性有不同的生命周期和可见性,如全局的ServletContext属性,局部的ServletRequest属性。 4. **线程安全**:属性管理需要考虑线程并发访问的问题,尤其是共享资源。 【会话状态管理...
EL(Expression Language)则提供了一种简洁的方式来访问作用域中的对象。 **Servlet与JSP的交互** Servlet通常负责处理业务逻辑,而JSP用于生成视图。在MVC(Model-View-Controller)设计模式中,Servlet充当...
5. **EL(Expression Language)相关类**:EL提供了一种简洁的方式来访问JavaBean属性或其他作用域内的对象,简化了页面中的表达式处理。 在开发环境中,将servlet-api.jar和jsp-api.jar添加到项目的类路径...