@ManagedProperty on #{param} does not work in @ViewScoped
My bean has this:
@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().getExternalCon开发者_运维问答text().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;
}
}
And the destination Facelet has this:
<f:metadata>
<f:viewParam name="id" value="#{bookBean.id}">
<f:event type="preRenderView" listener="#{bookBean.init}" />
</f:viewParam>
</f:metadata>
Through testing, I've noticed that @ManagedProperty
and @PostConstruct
only work with @RequestScoped
bean.
For @ViewScoped
bean, I found that I had to do this FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")
to get the value of the id
parameter.
Is this the only way to get a request parameter's value with @ViewScoped
?
Any thoughts?
The view scope is broader than the request scope. The @ManagedProperty
can only set properties which have the same or broader scope as compared to the managed bean's scope.
Just keep using <f:viewParam>
with <f:event>
. You should only not nest them in each other.
<f:metadata>
<f:viewParam name="id" value="#{bookBean.id}" />
<f:event type="preRenderView" listener="#{bookBean.init}" />
</f:metadata>
with
@ManagedBean
@ViewScoped
public class BookBean implements Serializable {
private String id;
public void init() {
if (id != null) {
currentBook = bookService.find(id);
}
}
// ...
}
The <f:viewParam>
will set the request parameter and the <f:event>
will execute the listener method after setting of those parameters.
The @PostConstruct
works fine on view scoped beans as well, but it only runs directly after bean's construction and all dependency injections are been set (such as @ManagedProperty
, @EJB
, @Inject
, @Resource
, etc). The <f:viewParam>
however sets the property thereafter, so it's not available in @PostConstruct
.
Here is another method for getting a request parameter inside a ViewScoped bean. This would be what #{param.device} would get in a RequestScoped bean. This has the advantage of not requiring any tags in the presentation layer.
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;
}
精彩评论