关于请求对象行为的混淆

时间:2013-02-05 20:31:55

标签: java jsp servlets scope

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

  1. 我已经创建了一个servlet(控制器),它将请求发送到JSP

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

  3. 我可以在JSP中访问请求对象的参数和属性,而无需任何
    问题

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

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

  6. 在第二个JSP中,当我从会话对象中检索请求对象时,我得到了一个 来自检索到的请求对象的所有属性的null值。
  7. 只有在检索到时,我才能访问检索到的请求对象的参数 使用request.getParameter()方法在我的第一个JSP中至少进行一次参数 否则他们在我的第二个JSP中返回null。
  8. 我对这些东西很陌生并且对这种行为感到困惑。为什么我的请求对象的属性被“擦除”而参数保持不变(只要我访问了我的第一个JSP中的参数;这对我来说更令人困惑,因为它没有意义IMO)

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

2 个答案:

答案 0 :(得分:3)

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

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

修改

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

答案 1 :(得分:2)

Java EE 5中有 4 范围。在Java EE 6Java EE 7中都有 5 范围。最常用的是:

  • 请求范围
  • 会话范围
  • 应用程序范围(Web上下文)

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

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

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

在此请求中存储属性。 属性在两者之间重置   请求即可。这种方法最常用于   RequestDispatcher的。
  ...

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

HttpSession中设置的那些属性(在会话范围中)只要会话存在就会生效,当然,只有用户可以使用这些属性。会话属于。

对于上下文属性,它们可用于整个Web应用程序(应用程序范围),对于所有用户,只要Web应用程序存在,它们就可以使用。


作为结论,如果您之前在会话中设置了一个属性,只要会话处于活动状态,它就可供同一用户使用。

希望这会对你有所帮助。

<强> P.S。
也许这篇文章也对您有用:How Java EE 6 Scopes Affect User Interactions
本文唯一使用 Annotations 进行范围确定,但您会明白这一点。