2

我正在使用JSF 2prettyfaces开发一个 Web 应用程序。我@ViewScoped用漂亮的注释注释了我的一个 bean。这就是我所拥有的:

@ManagedBean
@ViewScoped
@URLMapping(parentId = "app-list", id = "app-view", pattern = "/detail/#{appId}",
    viewId = "/system/manage_app/content/app_detail/app_detail.xhtml")
public class NavegableAppView extends SystemNavegable {

/**

基本上,它显示了安装在我的系统中的应用程序的详细信息。这个 bean 可以通过两种方式实例化,传递#{appId}参数,它指示我要加载的应用程序的 id,或者没有那个参数,在这种情况下,bean 将从一个@SessionScopedbean 中恢复这个 id。

这就是页面/system/manage_app/content/app_detail/app_detail.xhtml管理参数的方式:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
template="/templates/general_template.xhtml">

<ui:define name="metadata">
    <f:metadata>
        <f:viewParam id="appId" name="appId"
            value="#{navegableAppView._ParamApp}" required="false" />
        <f:event type="preRenderView"
            listener="#{navegableAppView.initialize}" />
    </f:metadata>
</ui:define>

<ui:define name="general_content">
    <p:panel>
<!--More stuff-->

这里的问题是我想要NavegableAppView创建 bean,有或没有参数。我已经尝试过这种方法<p:button value="prueba" outcome="pretty:app-view" />,但它限制了我只能做结果<p:commandButton value="prueba2" action="pretty:app-view" ajax="false" />,这相当于调用一个操作方法并返回导航案例(这就是我真正想要的)。

第一选择正确地创建 bean 并从会话中加载值。第二种情况,给我这个错误:

 HTTP 500 - PrettyFaces: Exception occurred while building URL 
 for MappingId < app-view >, Required value < #{appId} > was null

所以我的目标bean没有被构建。我已经尝试将参数手动添加到导航案例中:return pretty:app-view?appId=1它可以工作,但我希望目标 bean 从会话本身中恢复它。我是否必须在我的操作方法中调用重定向或类似的东西?

汇集你的想法。

4

1 回答 1

2

所以你实际上遇到了 PrettyFaces 的“边缘”效果之一。您定义的“appId”参数实际上既是参数名称,也是用于构建链接的 EL bean 值位置。

@URLMapping(parentId = "app-list", id = "app-view", pattern = "/detail/#{appId}",
viewId = "/system/manage_app/content/app_detail/app_detail.xhtml")

当您使用 PrettyFaces 的回发操作导航功能时,它需要一个 EL bean 名称。现在,碰巧的是,由于您没有在@URLMapping注释中提供参数名称,PrettyFaces 无论如何都会尝试使用参数名称,并希望它能找到您想要的。在这种情况下,显然没有名为 的 bean 值#{appId}

您实际上是在混合尝试解决同一问题的两种类型的功能。您的<f:metadata><f:viewParam>定义与 PrettyFaces 对其路径参数和操作方法所做的事情相同。您应该使用一种或另一种机制。如果您真的想混合它们,那么正如您所说,您应该从您的调用实际导航<h:commandButton>,如下所示:

<p:commandButton value="prueba2" action="#{navegableAppView.goToAppId}" ajax="false" />

然后,您需要确保返回带有appId参数的有效 JSF2 导航字符串,例如:

public String goToAppId() {
    return "/system/manage_app/content/app_detail/app_detail.xhtml?faces-redirect=true&appId=" + appId";
}

PrettyFaces 将了解您正在重定向到已映射的 URL,并将对该 URL 执行出站重写,并将您发送到正确的位置/detail/#{addId}。这都在文档中。

最后一个选项是简单地删除<f:metadata>and <f:viewParam>,并使用内置的 PrettyFaces 功能来管理视图参数。只需删除元数据并将您的更新@URLMapping到此,就可以解决您的问题:

@ManagedBean
@ViewScoped
@URLMapping(parentId = "app-list", id = "app-view", pattern = "/detail/#{appId : navegableAppView._ParamApp}",
viewId = "/system/manage_app/content/app_detail/app_detail.xhtml")
public class NavegableAppView extends SystemNavegable {

@URLAction
public String initialize() {
if ( appId != null ) {
      this.item = appsDB.findById(appId);
      return null;
    }

    // Add a message here, "The item {..} could not be found."
    return "pretty:app-list";
}

这就是使用 PrettyFaces 初始化页面的方式。归根结底,如果您使用pretty:mappingId导航,则应该使用 PrettyFaces 功能。如果您打算使用普通的 JSF2 样式导航,在其中指定视图 ID 和 URL 的所有参数,那么您可以混合匹配(只要您在 URL 映射中使用命名路径参数。

我希望这有帮助。

于 2013-01-24T15:35:54.037 回答