我需要将参数(POST)传递给@managedBean,我使用了这样的托管属性:
@ManagedProperty(value = "#{param.id}")
private int id;
Bean的范围是ViewScope
我最终得到了这个错误:
无法创建托管bean收据。发现了以下问题: - 表达式#{param.id},request引用的对象的范围比引用的托管bean视图范围短
我该怎么办?
arjan看看:
我的页面: Facelet标题
<form method="post" action="faces/index.xhtml">
<input name="id" value="4" />
<input type="submit" value="submit" />
</form>
<h:form>
<h:commandLink value="click" action="index">
<f:param id="id" name="id" value="20"/>
</h:commandLink>
</h:form>
答案 0 :(得分:38)
两种方式:
使bean请求作用域并将视图作用域注入另一个@ManagedProperty
。
@ManagedBean
@RequestScoped
public class RequestBean {
@ManagedProperty(value="#{param.id}")
private Integer id;
@ManagedProperty(value="#{viewBean}")
private ViewBean viewBean;
}
视图范围bean在请求范围bean的@PostConstruct
和操作方法期间可用。您只需记住,当您在没有参数的情况下回发到同一视图时,id
可能会丢失。
或者,在bean初始化期间从请求参数映射中手动获取它。
@ManagedBean
@ViewScoped
public class ViewBean {
private Integer id;
@PostConstruct
public void init() {
id = Integer.valueOf(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"));
}
}
这样,初始id
在整个视图范围内都可用。
答案 1 :(得分:6)
作为直接从bean中的请求获取参数的替代方法,您可以使用view parameters
。
需要在使用托管bean的Facelet上声明这些内容,如下所示:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<h:body>
<f:metadata>
<f:viewParam id="id" name="id" value="#{myBean.id}" />
</f:metadata>
<!-- Rest of Facelet here -->
</h:body>
</html>
如果您现在请求此页面,将使用为id参数提供的请求值调用辅助bean的setter。这适用于GET
和(非面孔)POST
请求。
优点是您可以在此处使用标准JSF转换器和验证器。当然,如果您的托管bean没有绑定到特定视图,那么这个解决方案就不太理想了。
需要注意的一个小特点是,在提供视图参数的初始请求之后执行正常的面向回发时,将再次调用bean中的setter,即使bean在视图范围内并且没有新的值是明确提供的。
为了测试这是否有效,我使用了以下托管bean:
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
@ManagedBean
@ViewScoped
public class MyBean {
Long id;
@PostConstruct
public void test() {
System.out.println("post construct called");
}
public void actionMethod(ActionEvent event) {
System.out.println("action called");
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
以下Facelet:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<h:body>
<f:metadata>
<f:viewParam id="id" name="id" value="#{myBean.id}" />
</f:metadata>
<h:outputText value="#{myBean.id}"/>
<h:form>
<h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
</h:form>
<form method="post">
<input name="id" value="4" />
<input type="submit" value="submit" />
</form>
</h:body>
</html>
在输入字段中输入一个数字,然后单击“提交”按钮。如果数字打印在屏幕上,则测试成功。请注意,第二个表单是常规表单,不会发布任何JSF状态。我在JBoss AS 6上测试了这个并且它可以工作。将id参数证明为GET参数也可以。