问题
I'm trying to inject the value of one sessionscoped bean into a viewscoped bean but it keeps returning null, here's a snippet:
import javax.faces.application.FacesMessage;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
//Class for managing the current logged-in user
@ManagedBean(name="user")
@SessionScoped
public class User implements Serializable{
private String userName;
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserName() {
return this.userName;
}
And it's used in:
@ManagedBean(name="databrowser")
@ViewScoped
public class dataBrowser implements Serializable {
private List<UploadData> dataItems;
private SelectItem[] dataTypeOptions, qualityOptions, accessOptions;
private UploadData selectedData;
private String filelocation;
@ManagedProperty(value="#{user.userName}")
private String userName;
public String getUserName() {
return this.userName;
}
dataBrowser is used to populate a Primefaces datatable, when it's called userName is null and I'm not sure why.
回答1:
Recently I have problem with injecting nested managed bean properties by @ManagedProperties
too. Once injected it never changed. I did a workaround by evaluating EL in getter instead of injecting it.
Try that:
public String getUserName() {
FacesContext context = FacesContext.getCurrentInstance();
return (String) context.getApplication().evaluateExpressionGet(context,"#{user.userName}", String.class);
}
You can also try injecting entire user
bean and get userName
field from it in getter.
回答2:
With all setters/getters in place, I was having the same problem (null reference to user) because of missing empty constructor in User class.
In the example you provided, the dataBrowser
and user beans are instantiated before constructing the table, so referencing #{dataBrowser.userName}
should already find the userName @ManagedProperty
correctly injected (not being a @PostConstruct
problem).
回答3:
I just came across the same problem, and found out by chance, that it is not working, if I try with firefox (actually icedove under linux), but well working, if I try with the eclipse build-in browser.
Even so this does not make sense to me, have you tried with different browsers already?
michal777's answer is very well working. I have extended it to this:
@ManagedProperty("#{nameBean}")
private NameBean nameBean;
public NameBean getNameBean() { return nameBean; }
public void setNameBean(NameBean nameBean) { this.nameBean = nameBean; }
public NameBean getNameBean_Workaround() {
FacesContext context = FacesContext.getCurrentInstance();
return (NameBean) context.getApplication().evaluateExpressionGet(context,"#{nameBean}", NameBean.class);
}
and later on:
if (nameBean != null) {
nameBean.setName("achsooo");
}
else {
getNameBean_Workaround().setName("achsooo2222");
}
Now, in the eclipse browser "achsooo" gets set, and in icedove "achsooo2222" gets set.
回答4:
#{user.userName}
is interpreted by JSF as getUser().getUserName()
So it is better to have a @ManagedProperty
of type User
, with its getter/setter methods getUser
/setUser
. With that you can access the user's name by #{user.userName}
.
回答5:
I had this problem, and the problem was actually twofold. (Note also that @ManagedProperty will only ever work in a @ManagedBean class and if that @ManagedProperty class is of the same or lesser scope (application, session, view, request, etc.).) Here is how I fixed it:
Problem 1: JSF is stupid and doesn't handle @ManagedProperty
injection properly in abstract
classes.
Solution:
- Make every class that uses
@ManagedProperty
be annotated with@ManagedBean
. - Make every
abstract
class that uses the property not be annotated with@ManagedProperty
and instead only provide abstract getter and setter methods that non-abstract classes will each override. - Use the
abstract
class's getter method instead of the @ManagedProperty itself inabstract
classes.
Problem 2: JSF is stupid and doesn't handle @ManagedProperty
injection properly in @ManagedBean classes not created by JSF (i.e. you are creating these classes yourself using new
).
Solution options:
- Let JSF create the class that uses the
@ManagedProperty
. - Use the following code:
MyClass example = Utils.getELValue("EL Expression Goes Here", MyClass.class);
public static <T> T getELValue(final String elName, final Class<T> clazz) {
FacesContext fc = FacesContext.getCurrentInstance();
return (T) fc.getApplication().getELResolver().getValue(fc.getELContext(), null, elName);
// Potential (untested) alternative:
// ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().getAttribute("")
}
来源:https://stackoverflow.com/questions/10024550/managedproperty-does-not-reflect-changes-and-keeps-returning-null