@ManagedProperty不反映更改并保持返回null

时间:2012-04-05 07:43:52

标签: jsf null managed-property

我正在尝试将一个sessioncoped bean的值注入到一个viewscoped bean中,但它一直返回null,这是一个片段:

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;
}

它用于:

@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用于填充Primefaces数据表,当它被称为userName为null并且我不确定原因时。

5 个答案:

答案 0 :(得分:2)

最近我也遇到了@ManagedProperties注入嵌套托管bean属性的问题。注入后它永远不会改变。我通过在getter中评估EL而不是注入它来做一个解决方法。

试试:

public String getUserName() {
    FacesContext context = FacesContext.getCurrentInstance();
    return (String) context.getApplication().evaluateExpressionGet(context,"#{user.userName}", String.class);
}

您还可以尝试在getter中注入整个user bean并从中获取userName字段。

答案 1 :(得分:0)

有了所有的setter / getter,我遇到了同样的问题( null 对用户的引用),因为缺少User class 中的空构造函数。

在您提供的示例中,dataBrowser和用户bean在构造表之前被实例化,因此引用#{dataBrowser.userName}应该已经找到正确注入的userName @ManagedProperty(不是{{1}问题)。

答案 2 :(得分:0)

我刚刚遇到同样的问题,并且偶然发现它不起作用,如果我尝试使用firefox(实际上是linux下的icedove),但是如果我尝试使用eclipse内置浏览器,那么工作正常。

即便如此,这对我来说没有意义,您是否尝试过不同的浏览器?


michal777的答案非常好用。我把它扩展到了这个:

    @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);
}

以及后来:

    if (nameBean != null) {
        nameBean.setName("achsooo");
    }
    else {
        getNameBean_Workaround().setName("achsooo2222");
    }

现在,在eclipse浏览器中,“achsooo”被设置,并且在icedove“achsooo2222”中被设置。

答案 3 :(得分:0)

#{user.userName}被JSF解释为getUser().getUserName()

因此,最好使用@ManagedProperty类型User及其getter / setter方法getUser / setUser。有了它,您可以通过#{user.userName}访问用户名。

答案 4 :(得分:0)

我有这个问题,问题实际上是双重的。 (另请注意,@ ManagedProperty只能在@ManagedBean类中工作,如果@ManagedProperty类具有相同或更小的范围(应用程序,会话,视图,请求等)。)以下是我修复它的方法:< / p>

问题1: JSF是愚蠢的,并且无法在@ManagedProperty类中正确处理abstract注入。

<强>解决方案:

  1. 使用@ManagedProperty对每个使用@ManagedBean的班级进行注释。
  2. 使用该属性的每个abstract类都不用@ManagedProperty注释,而只提供抽象的getter和setter方法,非抽象类将各自覆盖。
  3. abstract类中使用abstract类的getter方法而不是@ManagedProperty本身。
  4. 问题2: JSF是愚蠢的,并且不能在不是由JSF创建的@ManagedBean类中正确处理@ManagedProperty注入(即您使用new自己创建这些类)。

    解决方案选项:

    • 让JSF创建使用@ManagedProperty
    • 的类
    • 使用以下代码:
    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("")
    }