3

我一直在搞乱 servlet 和 JSP,但我对某些事情感到有些困惑:

  1. 我制作了一个 servlet(控制器),它将请求分派给 JSP

  2. 我在我的 servlet 中使用 setAttribute() 方法为请求对象设置了一些属性。

  3. 我可以毫无问题地在 JSP 中访问请求对象的参数和属性

  4. 现在,我使用
    session.setAttribute("test", request) 将请求对象作为属性存储在会话对象中。

  5. 我编写了第二个 JSP(
    当我单击特定按钮时,将通过 Javascript 从第一个 JSP 导航到它 - 通过使用 window.location 函数并将
    第二个 JSP 的地址作为值)

  6. 在第二个 JSP 中,当我从会话对象中检索请求对象时,我从检索到的请求对象的
    所有属性中获得了一个空值。
  7. 只有当我
    在我的第一个 JSP 中使用 request.getParameter() 方法至少检索了一次参数时,我才能访问检索到的请求对象的参数,
    否则它们在我的第二个 JSP 中返回 null。

我对这些东西真的很陌生,并且对这种行为感到困惑。为什么我的请求对象的属性被“删除”而参数保持不变(只要我在我的第一个 JSP 中访问了参数;这对我来说更令人困惑,因为它没有意义 IMO)

任何解释将不胜感激!提前谢谢你。

4

2 回答 2

3

这只是一个有根据的猜测,但我认为问题在于您选择的容器中的请求对象可能对其参数很懒惰:当您向它询问参数时,它会到达一些外部上下文并提取所需的数据,在同时缓存它。

然而,奇怪行为的原因并不重要。这个问题应该通过不在会话中保存请求来解决。请求对象只是您当前请求的句柄,而不是数据存储本身。它可能正在使用下面的任何机制,因为我们知道属性可能存储在 threadlocals 中。绝对没有任何合同可以使请求充当任何类型的档案。例如:如果我向安全主体询问这样一个存储的请求,这意味着什么?我的意思是“本届会议的现任负责人”吗?我的意思是“创建请求时的委托人”吗?

编辑:

出于纯粹的好奇,我只是看了看 Tomcat 的实现(我不知道您使用的是哪个容器),发现它支持我的主张:不仅大部分数据是懒惰地收集的,而且请求对象也被回收了!因此,如果您尝试将其存储在会话中然后使用,您可能会发现您正在使用其他人的请求。

于 2013-02-05T23:22:35.623 回答
2

Java EE 5中有4 个作用域。在Java EE 6Java EE 7中都有5 个作用域。最常用的是:

  • 请求范围
  • 会话范围
  • 应用范围(Web Context)

您可以通过设置适当的属性在上述所有范围内存储一些数据。

这是 Java EE API 文档中与请求范围相关的ServletRequest.setAttribute(String, Object)方法的引用:

void setAttribute(java.lang.String name,
                  java.lang.Object o)

在此请求中存储一个属性。在请求之间重置属性。此方法最常与 RequestDispatcher 结合使用。
...

因此,对于每个新请求,您在请求中设置的先前属性都将丢失。在请求中设置属性后,您必须将请求转发到所需的页面。如果您重定向,这将是一个全新的请求,因此之前设置的属性将丢失。(如果您仍想使用重定向,请阅读:Servlet Redirection to same page with error message

在HttpSession(在会话范围内)中设置的那些属性将与会话存在一样长,当然,只有会话所属的用户才能使用。

至于上下文属性,它们意味着对整个 Web 应用程序(应用程序范围)和所有用户都可用,而且只要 Web 应用程序存在,它们就会存在。


总而言之,如果您之前在会话中设置了一个属性,只要会话处于活动状态,同一用户就可以使用该属性。

希望这会帮助你。

PS
也许这篇文章对你也有用:Java EE 6 Scopes 如何影响用户交互
本文唯一使用Annotations进行范围界定的事情,但你会明白的。

于 2013-02-05T23:07:35.150 回答