Managed property value not updated when both beans

2019-04-13 05:14发布

问题:

I am seeing this strange behavior when using @ManagedProperty. I have 2 beans:

UserManager (SessionScoped)

@ManagedBean
@SessionScoped
public class UserManager extends BaseBean implements Serializable
{
   private static final long serialVersionUID = 1861000957282002416L;

   private User currentUser;

   public String login() 
   {
      // set value of currentUser after authentication
   }

   public User getCurrentUser() {
      return currentUser;
   }

   public boolean isLoggedIn() {
      return getCurrentUser() != null;
   }
}

CartBean (ALSO SessionScoped)

...
import javax.faces.bean.ManagedProperty;
...

@ManagedBean
@SessionScoped
public class CartBean extends BaseBean implements Serializable
{
   @ManagedProperty(value = "#{userManager.loggedIn}")
   private boolean loggedIn;

   public void updateCart(Movie selectedMovie)
   {
      if (!loggedIn) {
         return;
      }

      System.out.println("UPDATE CART REQUEST");

      int id = selectedMovie.getMovieID();

      if (cart.containsKey(id)) {
         cart.remove(id);
      }
      else {
         cart.put(id, selectedMovie);
      }
   }

   public void setLoggedIn(boolean loggedIn) {
      this.loggedIn = loggedIn;
   }
}

After logging in successfully, the value of loggedIn still remains false.

However, if I change the scope of CartBean to @ViewScoped, the value of loggedIn gets updated and I see the sysout.

As per my understanding and also after reading various articles, one can inject a managed bean or its property only if it is of the same or broader scope. But the "same scope" case does not seem to work in my code. What am I missing here?

I am using:

  • Mojarra 2.1.16
  • Spring 3.2
  • Hibernate 4.1
  • Tomcat 7.0.37

回答1:

@ManagedProperty annotation can only provide static injection, which means that the annotated property will get injected when and only when the holding @ManagedBean is instantiated.

When you deploy your application, I believe your CartBean was referenced right at the beginning through things like the View cart button, etc. As a consequence, the injection took place too early and since the bean is @SessionScoped, you will carry the initial false value till the end of time :).

Instead of injecting only the boolean field, you should, instead, inject the whole UserManager bean:

@ManagedBean
@SessionScoped
public class CartBean extends BaseBean implements Serializable {
   @ManagedProperty(value = "#{userManager}")
   private UserManager userManager;

   public void updateCart(Movie selectedMovie) {
       if (!userManager.isLoggedIn()) {
           return;
       }

       ...
   }
}


回答2:

The solution is using Omnifaces it worked for me each time the value change you will get the new value

@ManagedBean
@ViewScoped
public class CartBean extends BaseBean implements Serializable {

   private boolean loggedIn;

   public void updateCart(Movie selectedMovie) {
loggedIn=Faces.evaluateExpressionGet("#{userManager.loggedIN}");
       if (!userManager.isLoggedIn()) {
           return;
       }

       ...
   }
}


标签: jsf-2 el