我正在使用 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从会话本身恢复它。我是否必须在我的操作方法中调用重定向或类似的东西?
汇集您的想法。
答案 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映射中的参数。
我希望这会有所帮助。