在我的JSF应用程序中,我有两个页面list.jsf
和details.jsf
,每个页面都有自己的带有视图范围的控制器。在list.jsf
我有<h:commandLink>
调用操作并传递参数:
<h:commandLink value="details" action="#{listBean.goToDetails}" >
<f:param name="id" value="#{listBean.object.pk}"/></h:commandLink>
这是bean方法:
@ManagedBean
@ViewScoped
public class ListBean {
public String goToDetails() {
// some code
return "details?faces-redirect=true";
}
}
我在第二个bean中读取了这个参数:
Map<String, String> params = FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap();
this.setIdParam(params.get("id"));
当我运行此代码时,该参数不会传递给第二个bean实例。
但是,当我将导航更改为forward
(没有faces-redirect=true
)时,参数将被传递,我可以在details.jsf
中看到详细信息,但网址与当前页面不匹配。
所以我想做的是使用带有POST参数的“jsf隐式重定向”(不是转发)(f:param)。
答案 0 :(得分:6)
您无法使用POST重定向。
当您使用faces-redirect=true
时,您正在使用HTTP redirect,会发生什么:服务器向浏览器发送HTTP 302响应,并带有重定向URL,然后浏览器执行获取该URL的请求。
您可以做的是重定向到通过GET发送id
参数的网址,如下所示:
public void goToDetails(){
// some code
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext()
String id = object.getPk().toString();
ec.redirect(ec.getRequestContextPath() + "/details.jsf?id=" + id);
}
您可能想为此类事物创建一个util方法,例如Faces#redirect()
的OmniFaces library。
UPDATE:如评论中所述,也可以在返回字符串中添加id:
public String goToDetails(){
// some code
String id = object.getPk().toString();
return "details?faces-redirect=true&id=" + id;
}
答案 1 :(得分:5)
如果list.jsf
后面的支持bean不需要进行任何处理(从示例中它看起来不像),您应该直接通过details.jsf
链接到<h:link>
GET请求。
您可以使用<h:link value="details" outcome="details.jsf" >
<f:param name="id" value="#{listBean.object.pk}"/>
</h:link>
标记,如下所示:
<f:metadata>
<f:viewParam name="id" value="#{detailsBean.id}" />
</f:metadata>
在详细信息视图中,您可以声明视图使用GET参数并将其直接绑定到该视图的辅助bean:
detailsBean
此外,您可以直接验证和/或转换该参数,这样您的detailsBean
将获得正确类型的对象而不是基于字符串的ID。如果您在注入GET参数后需要在preRenderView
中进行任何后处理,则可以使用<f:metadata>
<f:viewParam name="id" value="#{detailsBean.id}" />
<f:event type="preRenderView" listener="#{detailsBean.preRenderView()}" />
</f:metadata>
事件:
{{1}}
工作示例:
另见: