我的bean有这个:
@ManagedBean
@ViewScoped
public class BookBean implements Serializable
{
@ManagedProperty(value = "#{param.id}") // does not work with @ViewScoped
private String id;
public void init()
{
id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")
if (id != null) {
System.out.println("ID: " + id);
currentBook = bookService.find(id);
}
}
@PostConstruct
public void post()
{
// does not work with @ViewScoped
System.out.println("ID: " + id);
currentBook = bookService.find(id);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
目标Facelet有这个:
<f:metadata>
<f:viewParam name="id" value="#{bookBean.id}">
<f:event type="preRenderView" listener="#{bookBean.init}" />
</f:viewParam>
</f:metadata>
通过测试,我注意到@ManagedProperty
和@PostConstruct
只与@RequestScoped
bean一起工作。
对于@ViewScoped
bean,我发现我必须执行FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")
才能获得id
参数的值。
这是获得@ViewScoped
请求参数值的唯一方法吗?
任何想法吗?
视图范围比请求范围更宽。@ManagedProperty
只能设置与托管bean的作用域相同或更广的属性。
继续使用<f:viewParam>
和<f:event>
。你只应该不把它们嵌套在一起。
<f:metadata>
<f:viewParam name="id" value="#{bookBean.id}" />
<f:event type="preRenderView" listener="#{bookBean.init}" />
</f:metadata>
@ManagedBean
@ViewScoped
public class BookBean implements Serializable {
private String id;
public void init() {
if (id != null) {
currentBook = bookService.find(id);
}
}
// ...
}
<f:viewParam>
将设置请求参数,<f:event>
将在设置这些参数后执行侦听器方法。
@PostConstruct
在视图作用域的bean上也工作得很好,但是它只在bean的构造和所有依赖注入被设置后直接运行(如@ManagedProperty
, @EJB
, @Inject
, @Resource
等)。然而,<f:viewParam>
随后设置了该属性,因此在@PostConstruct
中不可用。
下面是在ViewScoped bean中获取请求参数的另一种方法。这将是#{param.device}将在RequestScoped bean中获得的内容。这样做的优点是不需要在表示层中使用任何标记。
private int deviceID;
public int getDeviceID() {
if (deviceID == 0) {
String s = FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get("device");
try {
deviceID = Integer.parseInt(s);
} catch (NumberFormatException nfe) {
}
}
return deviceID;
}