我想了解Struts 2值堆栈与请求范围。 我希望struts2值栈与请求范围一样工作。
例如 我在struts 2中调用了action1,该操作执行了一些db任务并返回。它对一个名为cases的对象执行一些操作(类型为Cases,其中Cases是带有getter和setter的bean类)。 case对象在类级别声明。
action1导致视图呈现为jsp1。
jsp1再次有一些名为action2的动作。 action2导致与action1相同的java文件,但具有不同的方法。
现在,我想访问action1中使用的对象。在action1期间,案例被推送到Value Stack并在jsp1上被访问。
我只是尝试访问其getter方法,但它返回一个空值.... !!
关于怎么做的任何解决方案???还是可能的?我知道它是否可能然后vs和请求范围之间有什么区别...
答案 0 :(得分:1)
Dave说请求范围内的ValueStack是正确的。
但要实现您想要的目标,只需从数据库中获取一些数据,然后在多个操作/请求中使用此数据,就可以使用一些可能的方法:
1)让您的操作实现SessionAware接口,并编写一些代码以“手动”获取并将数据放入会话映射中。这种方法需要零额外配置,并且非常直接用于“无魔法”。另一方面,它会在您的动作类中添加样板代码,并要求您在完成操作后“手动”从会话中删除数据(或者,如果保存内存不重要,您可以将其保留在那里) 。
2)让您的操作实施ModelDriven界面并配置ScopedModelDrivenInterceptor以管理“案例”模型的会话范围。这不像SessionAware方法那么简单,因为它需要引用文档来向struts.xml添加一些非常具体的配置细节。它仍然需要添加样板代码,并且它不提供从会话中删除数据的简单方法。
3)使用Struts2 Conversation Plugin,并在case对象上放置@ConversationField注释,并在action1和action2方法上放置@ConversationAction注释。然后在你的struts.xml中你的包扩展了“struts2-conversation-default”包并在你的拦截器堆栈中包含“conversation”interceptor-ref。然后在你的jsp中,使用conversation tags。这种方法需要很少的样板和配置,但它确实通过注释将元数据添加到您的操作中(有些人会对此不屑一顾)并且确实需要学习更多。该插件具有额外的功能,例如允许同一对话的多个并发实例,自动删除数据以节省内存等,但是,根据您的需要,这可能是过度的。
您应用的最佳方法取决于您的要求和偏好。在操作类中应避免使用ActionContext.getContext().getSession();
访问会话对象,以支持SessionAware接口。
答案 1 :(得分:0)
您在第一个请求中创建的对象无法在第二个请求中引用,因为HTTP protocol is stateless。
所有Web编程(PHP,servlet jsp,asp等)都是一样的,因为web使用HTTP协议进行通信。
适合您的可行解决方案:
1.创建包含对象id的隐藏输入标记,这样当你第二次请求时,struts 2方法可以获取id(作为参数)并再次执行“action perform some db task”来重新创建相同的对象(再次创建它很昂贵,但这取决于您的需求)
或
2.在第一个请求中渲染jsp之前,可以将对象放在会话范围内(最好是执行此步骤,而不是使用jsp scriplet)。
Map session = ActionContext.getContext().getSession(); session.put("myCases","cases);
在第二个请求中,您可以访问该对象
Map session = ActionContext.getContext().getSession(); Cases cases=(Cases)session.get("myCases");
可以在任何actions / jsp中访问该会话,直到删除它为止。
Map session = ActionContext.getContext().getSession(); session.remove("myCases");
如果您尝试从会话中删除“myCases”后,您将获得null。