1

我想了解 Struts 2 值堆栈与请求范围。我希望 struts2 值堆栈与请求范围相同。

例如,我在 struts 2 中调用了 action1,该操作执行一些 db 任务并返回。它对称为 case 的对象执行一些操作(类型 Cases,其中 Cases 是具有 getter 和 setter 的 bean 类)。案例对象在类级别声明。

action1 导致要呈现的视图说 jsp1。

jsp1 再次具有一些称为 action2 的动作。action2 导致与 action1 相同的 java 文件,但具有不同的方法。

现在,我想访问在 action1 中使用的对象。在 action1 期间,案例被推送到值堆栈并在 jsp1 上访问。

我只是尝试访问它的getter方法,但它返回一个空值......!

关于如何做的任何解决方案???或者有可能吗?我知道它是否可能,那么 vs 和请求范围之间有什么区别......

4

2 回答 2

1

Dave 关于 ValueStack 在请求范围内的说法是正确的。

但是,为了实现您想要的,即从数据库中获取一些数据,然后在多个操作/请求中使用这些数据,可以使用一些可能的方法:

1) 让您的操作实现SessionAware接口,并编写一些代码来“手动”从会话映射中获取数据并将数据放入会话映射中。这种方法需要零额外配置,并且非常直接且“无魔法”。另一方面,它将样板代码添加到您的操作类中,并要求您在完成后“手动”从会话中删除数据(或者,如果节省内存不重要,您可以将其留在那里) .

2) 让您的操作实现ModelDriven接口并配置ScopedModelDrivenInterceptor以管理“案例”模型的会话范围。这比 SessionAware 方法简单,因为它需要参考文档以将一些非常具体的配置细节添加到您的 struts.xml。它仍然需要添加样板代码,并且它没有提供从会话中删除数据的简单方法。

3) 使用Struts2 Conversation Plugin,将 @ConversationField 注释放在你的案例对象上,并将 @ConversationAction 注释放在 action1 和 action2 方法上。然后在你的 struts.xml 中让你的包扩展“struts2-conversation-default”包并在你的拦截器堆栈中包含“conversation”interceptor-ref。然后在你的jsp中,使用对话标签. 这种方法需要很少的样板和配置,但它确实通过注释向您的操作添加元数据(有些人会对此皱眉),并且确实需要更多学习。该插件具有额外的功能,例如允许同一对话的多个并发实例,自动删除数据以节省内存等,但是,根据您的需要,这可能是矫枉过正。

您的应用程序的最佳方法将取决于您的要求和偏好。ActionContext.getContext().getSession();应避免在操作类中使用 SessionAware 接口访问会话对象。

于 2012-07-05T03:12:50.647 回答
0

您在第一个请求中创建的对象不能在第二个请求中引用,因为HTTP 协议是无状态的

对于所有 Web 编程(PHP、servlet jsp、asp 等)都是一样的,因为 Web 使用 HTTP 协议进行通信。

为您解决问题的可行解决方案:

1 .创建包含对象id的隐藏输入标签,这样当您第二次请求时,struts 2方法可以获取id(作为参数)并再次执行“action执行一些db任务”以重新创建相同的对象(再次创建它很昂贵,但这取决于您的需求)

或者

2 .在第一个请求中渲染jsp之前,您可以将对象放在会话范围内(最好在行动中执行此步骤,而不是在jsp scriplet中)。

Map session = ActionContext.getContext().getSession();
session.put("myCases","cases);

在第二个请求中,您可以访问该对象

Map session = ActionContext.getContext().getSession();
Cases cases=(Cases)session.get("myCases");

会话可以在任何操作/jsp 中访问,直到它被删除。

Map session = ActionContext.getContext().getSession();
session.remove("myCases");

如果您在从会话中删除后尝试访问“myCases”,您将获得 null。

于 2012-07-03T14:36:41.040 回答