繁体   English   中英

@ManagedProperty 不反映变化,一直返回 null

[英]@ManagedProperty does not reflect changes and keeps returning null

我试图将一个会话范围的 bean 的值注入一个视图范围的 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 时,我不确定为什么。

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

试试看:

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

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

在所有 setter/getter 到位的情况下,由于用户 class 中缺少空构造函数,我遇到了同样的问题( null对用户的引用)。

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

我刚刚遇到了同样的问题,偶然发现,如果我尝试使用 firefox(实际上是 icedove 在 linux 下),它不起作用,但是如果我尝试使用 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”。

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

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

我有这个问题,这个问题实际上是双重的。 (另请注意,@ManagedProperty 只会在 @ManagedBean class 中工作,并且如果 @ManagedProperty class 与 scope 相同或更小(应用程序、session、视图、请求等)。)以下是我修复它的方法:


问题 1: JSF 很愚蠢,没有正确处理abstract类中的@ManagedProperty注入。

解决方案:

  1. 使每个使用@ManagedBean的 class 都用@ManagedProperty注释。
  2. 使每个使用该属性的abstract class 不使用@ManagedProperty注释,而是仅提供非抽象类将分别覆盖的抽象 getter 和 setter 方法。
  3. abstract类中使用abstract类的 getter 方法而不是 @ManagedProperty 本身。

问题 2: JSF 是愚蠢的,不能在不是由 JSF 创建的 @ManagedBean 类中正确处理@ManagedProperty注入(即您正在使用new自己创建这些类)。

解决方案选项:

  • 让 JSF 创建使用@ManagedProperty的 class。
  • 使用以下代码:

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("")
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM