我一直在搞乱servlet和JSP,我对某些事情感到困惑:
我已经创建了一个servlet(控制器),它将请求发送到JSP
我使用setAttribute()方法在请求对象中设置了一些属性 的servlet。
我可以在JSP中访问请求对象的参数和属性,而无需任何
问题
现在我使用
将请求对象存储为会话对象中的属性
session.setAttribute(“test”,request)。
我已经编写了第二个JSP(从第一个JSP导航到它将通过
单击特定按钮时的Javascript - 使用window.location函数和
将第二个JSP的地址作为值)
我对这些东西很陌生并且对这种行为感到困惑。为什么我的请求对象的属性被“擦除”而参数保持不变(只要我访问了我的第一个JSP中的参数;这对我来说更令人困惑,因为它没有意义IMO)
任何解释都将不胜感激!提前感谢你。
答案 0 :(得分:3)
这只是一个有根据的猜测,但我认为问题在于您选择的容器中的请求对象可能对其参数很懒惰:当您向它请求参数时,它会触及某些外部上下文并提取所需的数据,同时缓存它。
尽管如此,这种奇怪行为的原因并不重要。问题应该通过不在会话中保存请求来解决。请求对象只是当前请求的句柄,而不是数据存储本身。它可能正在使用下面的任何机制,因为我们知道所有属性都可以存储在threadlocals中。绝对没有合同可以使请求充当任何类型的存档。例如:如果我问这样存储的安全主体请求,这意味着什么?我的意思是“当前的会议主席”吗?我是指“创建请求时的主体”吗?
修改强>
出于纯粹的好奇心,我只是偷看了Tomcat的实现(我不知道你正在使用哪个容器)并发现它支持我的声明:不仅大多数数据是懒惰地收集,而且请求对象被回收!因此,如果您尝试将其存储在会话中然后使用,您可能会发现您正在使用某人的其他请求。
答案 1 :(得分:2)
Java EE 5中有 4 范围。在Java EE 6和Java EE 7中都有 5 范围。最常用的是:
您可以通过设置适当的属性在上述所有范围中存储一些数据。
以下是关于请求范围的与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 进行范围确定,但您会明白这一点。