查看不同bean中的参数



我有一个名为trip.xhtml的页面,我使用以下代码从URL中取出参数:

<f:metadata>
    <f:viewParam name="tripid" value="#{tripBean.tripId}" />
    <f:viewParam name="seats" value="#{tripBean.seats}" />
    <f:event type="preRenderView" listener="#{tripBean.processParams}" />
</f:metadata>

TripBean看起来像这样(简化):

@ManagedBean
@RequestScoped
public class TripBean implements Serializable {
    private static final long serialVersionUID = -4885781058258859229L;
    private Long tripId;
    private int seats;
    // Getters and setters for tripId and seats

trip.xhtml页面的底部,我有一个h:link:

<h:link outcome="/customer/booking.xhtml" value="Book this trip"
    includeViewParams="true" />

我期望的是,当我点击这个链接时,我得到的URL是"/customer/booking.jsf?tripid=2&seats=1"之类的东西。只有当我在booking.xhtml页面上放置以下代码时才会出现这种情况:

<f:metadata>
    <f:viewParam name="tripid" value="#{tripBean.tripId}" />
    <f:viewParam name="seats" value="#{tripBean.seats}" />
</f:metadata>

虽然我真正想要的是使用另一个bean。将代码更改为:

<f:metadata>
    <f:viewParam name="tripid" value="#{bookingBean.tripId}" />
    <f:viewParam name="seats" value="#{bookingBean.seats}" />
</f:metadata>

BookingBean也有2个属性tripIdseats,它们与TripBean相同,但是当我现在尝试单击链接时,我只看到一个设置为0的座位参数。("/customer/booking.jsf?seats=0")

有没有人知道为什么当我试图使用另一个bean来存储它们时,我似乎不能将viewparams传递到另一个页面?如果不可能将其存储在另一个bean中,我如何将TripBean中的这些值放在BookingBean中?

我使用的快速解决方法:不使用includeViewParams="true",而是手动向链接添加参数(见下文)"修复"了问题。虽然我仍然想知道为什么它不会与includeViewParams工作!

<h:link outcome="/customer/booking.xhtml" value="#{msg['page.trip.booking']}">
    <f:param name="tripid" value="#{tripBean.tripId}" />
    <f:param name="seats" value="#{tripBean.seats}" />
</h:link>

f:viewParam的工作原理与h:inputText完全相同。这意味着它使用相同的表达式作为源(在呈现时)和目标(在更新模型时)。如果你有:

<h:inputText value="#{a.test}" />

你永远不会问"如何让inputTextb.foo读取并写入a.test",然而每个人似乎都期望f:viewParam有这样的行为。

无论如何,有一个简单的答案。要附加任何值到link,您只需要使用f:param:

<h:link outcome="/customer/booking.xhtml" value="Book this trip" >
    <f:param name="tripid" value="#{bookingBean.tripId}" />
    <f:param name="seats" value="#{bookingBean.seats}" />
</h:link>

与以下标签对应的链接内容:

<h:link outcome="/customer/booking.xhtml" value="Book this trip"
            includeViewParams="true" />

是在trip.xhtml视图请求的呈现-响应阶段生成的。如果您需要URL包含视图参数值,那么您必须在用于访问视图的URL中提供这些值,或者您必须在呈现-响应阶段完成之前在模型中设置这些值。如果不执行其中任何一个,生成的超链接将包含视图参数的默认值。

简单来说,你必须:

  • 确保trip.xhtml视图使用必要的参数访问:trip.xhtml?tripid=x&seats=y,特别是如果视图在任何时候都要使用参数访问。
  • 或者必须在JSF运行时呈现链接之前执行的方法中设置值。BookingBean类的构造函数或类中的@PostConstruct注释方法是设置这些值的理想场所。在视图中执行操作的情况下,您还可以在托管bean的其他方法中重置/更新bean的值。注意,JSF运行时将调用getTripIdgetSeats,以在结果URL中包含视图参数tripIdseats的值,因此您也应该验证这些方法的行为。

您的问题是为什么您无法在booking.xhtml的EL表达式中指定bookingBean,而是要求您指定tripBean的所谓意外值,这是由于link标签的includeViewParams属性将包括to-view而不是from-view的参数。简单地说,JSF运行时将调用bookingBean.getTripId()bookingBean.getSeats(),而不是tripBean.getTripId()tripBean.getSeats()

虽然这看起来可能违反直觉,但是您应该理解JSF规范对这种场景的处理方式是完全不同的。在用户执行的大多数交互中,组件的操作URL是在用户执行操作时生成的,而不是在此之前生成的。另一方面,link标记需要对URL进行先发制人的计算,因此JSF运行时将其视为"先发制人的导航"。在构造URL时,为了使URL有意义,与目标视图的视图参数相关的对象必须是可访问的。URL中值为0的原因是,在此评估期间创建了一个新的BookingBean实例,并使用默认值代替。很明显,您可以通过使用TripBean来避免这种情况(大多数includeViewParams示例都演示了这一点),或者您可以在构建BookingBean对象期间设置值。

相关内容

  • 没有找到相关文章

最新更新