@ManagedProperty does not reflect changes and keeps returning null

99封情书 提交于 2019-12-01 06:37:42

问题


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:

  1. Make every class that uses @ManagedProperty be annotated with @ManagedBean.
  2. 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.
  3. Use the abstract class's getter method instead of the @ManagedProperty itself in abstract 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!