Jsf @ManagedProperty不反映更改并始终返回null
我试图将一个sessionscoped bean的值注入到一个viewscoped bean中,但它始终返回null,下面是一个片段:Jsf @ManagedProperty不反映更改并始终返回null,jsf,null,managed-property,Jsf,Null,Managed Property,我试图将一个sessionscoped 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 managin
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;
}
@ManagedBean(name=“databrowser”)
@视域
公共类dataBrowser实现可序列化的{
私有列表数据项;
private SelectItem[]数据类型选项、质量选项、访问选项;
私有上传数据选择数据;
私有字符串文件位置;
@ManagedProperty(value=“#{user.userName}”)
私有字符串用户名;
公共字符串getUserName(){
返回此用户名;
}
dataBrowser用于填充Primefaces数据表,当它被称为userName时,它为null,我不知道为什么。最近我也遇到了通过
@ManagedProperties
注入嵌套托管bean属性的问题。一旦注入,它就不会改变。我通过在getter中计算EL而不是注入EL来解决问题
试试看:
public String getUserName() {
FacesContext context = FacesContext.getCurrentInstance();
return (String) context.getApplication().evaluateExpressionGet(context,"#{user.userName}", String.class);
}
您还可以尝试注入整个
user
bean,并在getter中从中获取userName
字段。在所有setter/getter就绪的情况下,我遇到了相同的问题(null对用户的引用),因为在用户类中缺少空构造函数
在您提供的示例中,
dataBrowser
和用户bean在构造表之前被实例化,因此引用{dataBrowser.userName}
应该已经找到正确注入的userName@ManagedProperty
(不是@PostConstruct
问题).我只是遇到了同样的问题,并且偶然发现,如果我尝试使用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浏览器中设置“Achsoo”,在icedove中设置“Achsoo2222”。{user.userName}
被JSF解释为getUser().getUserName()
因此,最好有一个
@ManagedProperty
类型的User
,它的getter/setter方法getUser
/setUser
。这样你就可以通过{User.userName}访问用户名了。我遇到了这个问题,而这个问题实际上是双重的。(还请注意,@ManagedProperty将只在@ManagedBean类中工作,如果@ManagedProperty类的作用域相同或更小(应用程序、会话、视图、请求等),下面是我修复它的方法:
问题1:JSF很愚蠢,在抽象类中不能正确处理@ManagedProperty
注入
解决方案:
使每个使用@ManagedProperty
的类都用@ManagedBean
注释
使每个使用该属性的抽象
类都不使用@ManagedProperty
进行注释,而是只提供非抽象类将各自重写的抽象getter和setter方法
使用abstract
类的getter方法,而不是abstract
类中的@ManagedProperty本身
问题2:JSF很愚蠢,在非JSF创建的@ManagedBean类中不能正确处理@ManagedProperty
注入(即,您自己使用新建
创建这些类)
解决方案选项:
- 让JSF创建使用
@ManagedProperty
的类
- 使用以下代码:
MyClass-example=Utils.getELValue(“EL表达式在这里”,MyClass.class);
公共静态T getELValue(最终字符串elName,最终类clazz){
FacesContext fc=FacesContext.getCurrentInstance();
返回(T)fc.getApplication().getELResolver().getValue(fc.getELContext(),null,elName);
//潜在(未经测试)备选方案:
//((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().getAttribute(“”)
}
您是否有用于用户名的setter
?您需要一个setter才能使注入工作……您还需要@ViewScoped bean中的setter。这会引发异常,而不是返回null
。很抱歉,复活节周末的回复太晚了-是的,很抱歉,我在getter代码之后直接有了这个setter:public void setUserName(stringusername){this.userName=userName;}解决了它->最终移动了我的函数并使用@PostConstruct来确保在使用变量之前先进行注入
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("")
}