【问题标题】:JSF: navigationJSF:导航
【发布时间】:2009-06-30 10:48:24
【问题描述】:

我必须警告你:这个问题可能很愚蠢,但我现在似乎无法理解它。

我有两个托管 bean,比如说 A 和 B:

class A
{
    private Date d8; // ...getters & setters
    public String search()
    {
        // search by d8
    }
}

class B
{
    private Date d9; //...getters & setters
    public String insert()
    {
         // insert a  new item for date d9
    }    
}

然后我有两个 JSP 页面,pageA.jsp(搜索页面)和pageB.jsp(输入页面)。 我想做的是在 pageB 中放置一个 commandbutton 以便通过参数 d9 打开搜索页面 pageA > 不知何故,或者直接在 b.insert() 之后导航到 pageA。我想做的是在插入后显示搜索结果。

也许只是我看不到清晰、简单的解决方案,但我也想知道这里的最佳做法是什么......

我想到了这些可能的解决方案:

  1. 在 **B** 中包含 **A** 并将命令按钮与 **b.a.search** 链接
  2. 将 **d9** 作为 **hiddenInput** 传递并在 **A** 中添加新方法 **searchFromB**(丑陋!)
  3. 将两个 bean 合并为一个

【问题讨论】:

  • 将日期(其长值)作为 URL 参数是否可以接受?这些 bean 的作用域是什么?他们有任何其他状态或目的吗?也就是说,为简洁起见,您是否删除了其他变量? A中除了去B还有其他导航结果吗?
  • 这个场景(稍微)复杂一些,我想通过合并两个 bean 或将一个包含到另一个中来避免进一步纠结。我会考虑传递参数,正如你(和其他一些人)建议的那样,tnx。

标签: java jsf navigation


【解决方案1】:

JSF 1.1/1.2 raw 没有提供简单的方法来做到这一点。 Seam/Spring 都有解决这个问题的方法,您可以做一些事情。 JSF 2 发布后也应该有解决方案。

可能最简单和最方便的方法是将两个 bean 合并为一个并使其具有会话范围。当然,担心的是这个 bean 不会被删除并保持在会话中,直到会话超时。是的内存泄漏!

另一种解决方案是将日期作为 GET 参数传递。例如,您的操作方法可以调用

FacesContext.getCurrentInstance().getExternalContext().redirect("pageB?d9=" + convertDateToLong(d9));

然后获取另一边的参数。

【讨论】:

  • 好吧,我想我应该提前更好地计划编码,但我会尝试这种“传递参数”的解决方法,看看它是否能让应用程序正常工作。我仍然没有(也不喜欢)JSF... :(
  • JSF raw,在其当前的化身中,有它的缺陷。绝对真实。导航模型是最大的模型之一。然而,基于组件的概念在 IMO 中非常好,我使用的框架(Seam、Facelets、IceFaces 有时还有 RichFaces)让我能够绕过 JSF 的问题。 Seam,IMO,是 JSF 的杀手级应用。如果你打算进行长时间的 JSF 开发,我强烈建议你看看 seam。
【解决方案2】:

您应该在 faces-config.xml 中配置导航流程。在理想情况下,您将返回一条决定流程的“状态”消息。在以下链接阅读更多信息: http://www.horstmann.com/corejsf/faces-config.html http://publib.boulder.ibm.com/infocenter/rtnlhelp/v6r0m0/index.jsp?topic=/com.businessobjects.integration.eclipse.doc.devtools/developer/JSF_Walkthrough8.html

就将值从一页传递到另一页而言,您可以使用支持 bean。更多关于支持豆在这里: http://www.netbeans.org/kb/articles/jAstrologer-intro.html http://www.coderanch.com/t/214065/JSF/java/backing-beans-vs-managed-beans

希望我已经理解并正确回答了您的问题

bean 之间共享值的方式

FacesContext facesContext = FacesContext.getCurrentInstance();
Application app = facesContext.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesContext.getELContext();
ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
return valueExp.getValue(elContext);

在上面的代码中,“表达式”类似于#{xyzBean.beanProperty} 由于 JSF 使用单例实例,您应该能够访问来自其他 bean 的值。如果您找到有关此技术的更多详细信息,我相信您会得到您想要的。

【讨论】:

  • 嗯,我了解了 JSF 背后的总体思路。不过,这是一个特殊情况:我希望两个 bean 交换参数,而不是普通的普通流程。
  • 我已经编辑了我的帖子以反映一个方面,您至少可以从中找出 bean 之间的属性值。希望对您有所帮助。
【解决方案3】:
  1. 添加引用 B'insert 方法的 commandButton 动作属性

<h:commandLink action="#{b.insert}" value="insert"/>

  1. 在B'insert方法中,添加d9参数作为请求参数。然后从 insert 方法返回一个任意字符串。

FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().getRequestMap().put("d9", d9);

  1. 然后转到 faces 上下文并添加从 B 到 A 的导航,其中“from-outcome”作为您从 insert 方法返回的任意字符串。但是不要将重定向标签添加到导航标签,因为它会破坏来自 B 的请求,并且您添加的参数 (d9) 将被清除。

<from-outcome>return string of insert method</from-outcome>
<to-view-id>address of A</to-view-id>

  1. 然后,您可以通过在其构造函数或更合适的位置(getter)从请求映射中获取 A 类中的“d9”。如果您想稍后跟踪它,可以将其添加到会话范围或将其放置到隐藏变量中。

在A类中,当页面被导航时,A应该被初始化,因为它将被引用。

FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().getRequestMap().get("d9", d9);

抱歉,我无法提供完整的代码,因为我在这里不知道,它的互联网机器正在工作。因此,我无法提供详细信息。

【讨论】:

  • 我会试试这个。虽然我不喜欢围绕 JSF 机制工作的想法,但我认为这可能是唯一的方法。
【解决方案4】:

在我看来,最简单的方法是第三个选项——在同一个类中同时拥有查询和插入方法。你可以这样做:

public String query () {
//... 
}

public String Insert() {  
 //insert
return Query(); }

如果您的类是托管 Bean,您可以从类 B 加载类 A 并在插入方法中调用 A.query()结束。 A 类也可以有

<managed-bean-scope>session</managed-bean-scope>

faces-config.xml中的参数,加载时不会再次实例化。

【讨论】:

  • 会话范围 bean 很好,但要小心摆脱它们,否则大量用户会很快消耗掉你的内存。
猜你喜欢
  • 1970-01-01
  • 2011-11-22
  • 2013-01-22
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多