PrettyFaces错误与必需属性

时间:2013-01-23 16:22:27

标签: jsf-2 navigation prettyfaces

我正在使用 JSF 2 prettyfaces 开发一个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} param,它表示我想要加载的应用程序的id,没有该参数,在这种情况下,bean将恢复此来自@SessionScoped bean的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,有或没有param。我试过这种方式<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从会话本身恢复它。我是否必须在我的操作方法中调用重定向或类似的东西?

汇集您的想法。

1 个答案:

答案 0 :(得分: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会尝试使用参数名称,并希望它能找到你想要的。在这种情况下,显然没有名为#{appId}的bean值。

您真正混合了两种尝试解决同一问题的功能。您的<f:metadata><f:viewParam>定义与PrettyFaces使用其路径参数和操作方法执行的操作相同。您应该使用一种或另一种机制。如果你真的想混合它们,那么正如你所说,你应该<h:commandButton> invoking actual navigation,如下:

<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}。这是all in the docs.

最终选项只是删除<f:metadata><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映射中的参数。

我希望这会有所帮助。