【问题标题】:Sharing data between ViewScoped controllers在 ViewScoped 控制器之间共享数据
【发布时间】:2013-04-05 13:44:02
【问题描述】:

我有一个控制器,用户可以在其中将信息填写到表单中。保存表单时,会创建 JPA 对象并将其持久化到数据库中,并且用户会被重定向到另一个控制器以查看表单。我对在控制器之间传递整个对象不感兴趣,只是表示对象的字符串。我可以从数据库中重新加载对象,但是由于加载时间很慢,有什么方法可以在不访问数据库的情况下传递数据?

编辑: 当一个控制器重定向到另一个控制器时,我有兴趣将字符串从第一个控制器“发送”到重定向的控制器,以便显示这些字符串。

感谢您的帮助!

编辑 2:

这是第一个控制器中的代码:

//Called by a commandButton
public String saveForm() {
    //Objects are created and persisted to DB
    //Store the Objects' names as strings. These are the values I want to access in the second controller
    return "view_form.jsf?formId=" + formId.toString() + "&faces-redirect=true";
}

在名为viewForm 的第二个控制器中,我正在使用viewParam 加载formId:

<f:metadata>
  <f:viewParam name="formId" value="#{secondController.formId}" required="true"/>   
  <f:event type="preRenderView" listener="#{secondController.loadForm}"/>
</f:metadata>

loadForm 中,我想访问在saveForm 中创建的字符串。 我目前正在查看 Rodmar Conde 发布的关于在 Session Map 中存储数据的链接。这是解决这个问题的正确方法吗?

感谢您迄今为止的帮助!

【问题讨论】:

  • 我不确定我是否理解您的具体问题。如果您的意思是像 action="#{otherBean.doSomething(oneBean.entity)}" 那样在 viewscoped bean 之间传递数据,那么这些数据不会以任何方式暴露在 HTML/HTTP 中,并且不可能影响“加载时间”。请澄清具体问题。
  • @BalusC 我已将我的问题编辑为更具描述性。
  • 这真的是重定向到新的 GET 请求还是回发时的导航(转发)?
  • 您可以在控制器1中将字符串保存到HttpSession对象中,然后您可以在控制器2中恢复它们。 Saving data to session in JSF
  • @BalusC 我不完全确定我是否理解其中的区别。当按下“保存”命令按钮时,我的支持 bean 中的一个动作被调用,我计划从那里重定向到另一个控制器/页面。抱歉,不清楚,我刚刚开始使用 JSF/JEE。

标签: jsf view-scope


【解决方案1】:

代码看起来不错。对于需要通过幂等请求打开目标页面的情况,这也是推荐的方法。有关一些一般提示,另请参阅 How to navigate in JSF? How to make URL reflect current page (and not previous one)

您真正的问题显然只是数据库性能(尽管正确索引表上的单个选择应该相对便宜,但确保它不仅仅是连接成本(使用连接池)或网络延迟(主机数据库服务器靠近网络服务器))。在持久层中引入一种二级缓存可能会有很大帮助。使用关键字“二级缓存”或“二级缓存”参考相关持久层的文档。

请注意,这超出了 JSF 的范围。滥用 JSF 会话范围是另一种方式,但不是正确的方式。在由 GET 请求分隔的两个视图范围 bean 实例之间共享数据是不可能的,因为它们的生命周期结束并以 GET 请求开始。另见JSF ViewScoped variable not surviving redirect to same page

【讨论】:

    【解决方案2】:

    这就是我解决的问题。将会话中的值保存在第一个ViewScoped 控制器中,如下所示:

    ExternalContext etx = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletRequest httpReq = (HttpServletRequest)etx.getRequest();
        HttpSession session = httpReq.getSession();
        session.setAttribute("formId", "formId_value_here"); //use a map if you have multiple values
    

    并检索第二个ViewScoped 控制器(或任何地方)的PreRenderView 中的值,如下所示:

    ExternalContext etx = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletRequest httpReq = (HttpServletRequest)etx.getRequest();
    HttpSession session = httpReq.getSession();
    String formId = (String)session.getAttribute("formId");
    

    希望这对某人有所帮助。

    【讨论】:

    猜你喜欢
    • 2015-12-15
    • 2014-03-22
    • 2015-05-20
    • 2013-05-28
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    相关资源
    最近更新 更多