从后端Bean A传输JSF属性到后端Bean B

3
我目前正在深入学习JSF 2.0,但对于从一个视图到另一个视图传输托管bean属性的理解还有些欠缺。我进行了一些搜索,但没有找到真正好的例子,所以如果有人能指向教程或稍微解释一下这些事情,我会非常感激。
所以这是我的场景:
我正在开发一个小型游乐日历应用程序。第一个视图select.xhtml包含日历选择器,在那里用户可以选择特定日期:
<html>
  ...
  <h:form>

    <!-- Calendar selector from primefaces -->
    <p:calendar value="#{calendarSelect.date}" mode="inline" navigator="true" />

    <p:commandButton value="Show entries for date" action="day" />
    ...

我的相应支持bean看起来像这样:

@ManagedBean(name="calendarSelect")
@RequestScoped
public class CalendarSelectComponent {

  private Date date = null;

  ... // Getters and setters

现在,当我从select.xhtml提交表单后,我会被重定向到day.xhtml页面。
<html>
  ...
  <h:form>

    The current day ist:
    <h:outputText value="#{calendarEdit.date}">
      <f:convertDateTime pattern="dd.MM.yyyy" />
    </h:outputText>

现在的后备Bean看起来像这样:

@ManagedBean(name="calendarEdit")
@ViewScoped
public class CalendarEditComponent implements Serializable {

  private Date date = null;
  private CalendarEntryBean currentEntry = null;
  private List<CalendarEntryBean> allEntries = null;

  ....

我现在要解决这个问题:如何将date参数从选择器传递到编辑器?我尝试了许多选项,其中一个是这样的:
<p:commandButton value="Show entries for date" action="day" />
  <f:setPropertyActionListener target="#{calendarEdit.date}" value="#{calendarSelect.date}" />
</p:commandButton>

调试器显示,确实,calendarEditdate属性中填充了来自calendarSelect的值,但由于day.xhtml是一个新视图,正在创建一个新的CalendarEditComponent后备bean,而不是我用选择器在select视图中填充日期的那个后备bean。
我读到的一个解决方案是创建一个SessionScoped后备bean,它可以保留所有值。但我认为这不是它应该工作的方式,因为我并不真正需要会话中的信息,我只想让它从A到B“旅行”。使用基于会话的方法的另一个缺点是,在会话中只能使用一个选择器和一个编辑器,这在多窗口浏览等情况下是不可接受的。
我真的不认为我是第一个遇到这种情况的人,我相信JSF为此提供了一种优雅的解决方案,但我还没有找到那个解决方案。
所以,如果有人知道如何解决这个问题-我在听!;-)
1个回答

2
<f:setPropertyActionListener> 在表单提交的调用操作阶段执行。因此它期望该值在那一点仍然存在。但是,由于您的选择bean是请求作用域的,所以在表单提交期间不再存在。相反,您想传递一个请求参数,在呈现响应期间内联输出。您可以使用 <f:param> 来实现这一点。
<p:commandButton value="Show entries for date" action="day" />
  <f:param name="date" value="#{calendarSelect.dateAsString}" />
</p:commandButton>

它将作为请求参数提供(请注意,由于HTTP的特性,它只能理解字符串)。您可以让JSF将请求参数设置为托管属性,但由于您的编辑bean是视图作用域,因此这不适用于@ManagedProperty。您必须通过ExternalContext自己收集它。
String dateAsString = externalContext.getRequestParameterMap().get("date");

的确,那样很笨拙。我会使用同一个bean和视图,并通过rendered属性切换选择/编辑表单的可见性。毕竟,编辑视图不能通过简单的GET直接打开/书签化,对吧? ;)


谢谢您的回复,我担心没有“完美”的方法。但是关于您的评论“编辑视图毕竟不能通过简单的GET直接打开/书签”,如果我需要这样的东西怎么办?如果我需要像“http://blaba/edit.jsf?userId=42”这样的URL,唯一的方法就是通过编程访问参数吗? - Christian Seifert
1
那就这么做吧。您可以使用带有 @ManagedProperty 的请求作用域 bean,也可以使用在构建期间从 externalcontext 中收集参数或使用 f:viewParam 参数的视图作用域 bean。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接