[英]@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
注入。
解决方案:
@ManagedBean
的 class 都用@ManagedProperty
注释。abstract
class 不使用@ManagedProperty
注释,而是仅提供非抽象类将分别覆盖的抽象 getter 和 setter 方法。abstract
类中使用abstract
类的 getter 方法而不是 @ManagedProperty 本身。 问题 2: JSF 是愚蠢的,不能在不是由 JSF 创建的 @ManagedBean 类中正确处理@ManagedProperty
注入(即您正在使用new
自己创建这些类)。
解决方案选项:
@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.