关于请求对象行为的混淆

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

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

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

  3. 我可以在没有任何内容的情况下访问JSP中的请求对象的参数和属性
    问题。

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

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

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

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

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

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

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

编辑:

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

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

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

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

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

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

在此请求中存储属性。 在请求之间重置属性 。 此方法通常与RequestDispatcher一起使用。

因此,对于每个新请求,您在请求中设置的先前属性将丢失。 在请求中设置属性后, 必须将请求转发到所需页面。 如果您重定向,这将是一个完全新的请求,因此先前设置的属性将丢失。 (如果您仍然希望使用重定向,请阅读: Servlet重定向到同一页面,并显示错误消息 )

在HttpSession (在会话范围内 )中设置的那些属性将在会话存在时生存,当然,仅对会话所属的用户可用。

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


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

希望这会帮助你。

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