@ManagedProperty does not reflect changes and keeps returning null

后端 未结 5 1976
花落未央
花落未央 2021-01-14 11:07

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.applicati         


        
相关标签:
5条回答
  • 2021-01-14 11:24

    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.

    0 讨论(0)
  • 2021-01-14 11:29

    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("")
    }
    
    0 讨论(0)
  • 2021-01-14 11:30

    #{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}.

    0 讨论(0)
  • 2021-01-14 11:31

    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).

    0 讨论(0)
  • 2021-01-14 11:42

    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.

    0 讨论(0)
提交回复
热议问题