我的问题类似于这个 issue 。我有一个 BaseBean ,它目前只有一个被注释为 @ManagedProperty 的属性。

但是,当我在操作方法命令按钮中访问此继承的托管属性的 getter 时,它返回 null。我调试并确认基础 bean 构造器被调用了两次 - 一次是在页面加载时,然后是在点击按钮时,如上述链接中所述。

我遵循了文章选择的答案以及 this 帖子中提到的建议,但无济于事。

以下是我的代码:

public abstract class BaseBean
{
   @ManagedProperty(value = "#{serviceLocator}")
   private IServiceLocator serviceLocator;

   public IServiceLocator getServiceLocator() {
      return serviceLocator;
   }

   public void setServiceLocator(IServiceLocator serviceLocator) {
      this.serviceLocator = serviceLocator;
   }
}
@ManagedBean
@ViewScoped
public class RegistrationBean extends BaseBean implements Serializable
{
   private static final long serialVersionUID = -6449858513581500971L;

   private String userID;
   private String password;
   private String firstName;
   private String lastName;
   private String email;
   private String addressLine1;
   private String addressLine2;
   private String city;
   private String state;
   private String pincode;

   private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationBean.class);

   /* getter / setters */

   public String register()
   {
      String nextPage = null;
      try {
         RegistrationDetails userDetails = ModelBuilder.populateRegistrationData(this);
         int registrationID = getServiceLocator().getUserService().registerUser(userDetails);
         LOGGER.info("Registered user successfully. Registration ID - {}", registrationID);
         nextPage = "success";
      }
      catch (RegistrationException e) {
         LOGGER.error(e.getMessage());
      }
      return nextPage;
   }

   public void checkUserExists()
   {
      int regID = getServiceLocator().getUserService().findUser(getUserID());

      if(regID > 0) {
         FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "User already exists !!", null);
         FacesContext.getCurrentInstance().addMessage(null, message);
      }
   }
}

为什么会在表单提交时再次调用构造函数??? :/

即使在通过 ajax 调用 userID 字段的 blur 事件的 checkUserExists() 方法中,getter 也返回 null。

编辑 :添加了 ServiceLocator 的代码..
@ManagedBean
@ApplicationScoped
public class ServiceLocator implements IServiceLocator
{
   private static final String USER_SERVICE = "userService";
   private static final String MOVIE_SERVICE = "movieService";

   @PostConstruct
   public void init() {
      final ServletContext sc = FacesUtils.getServletContext();
      this.webAppContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
      this.userService = (IUserService) webAppContext.getBean(USER_SERVICE);
      this.movieService = (IMovieService) webAppContext.getBean(MOVIE_SERVICE);
   }

   private ApplicationContext webAppContext;

   private IUserService userService;

   private IMovieService movieService;

   @Override
   public IUserService getUserService() {
      return userService;
   }

   @Override
   public IMovieService getMovieService() {
      return movieService;
   }
}

最佳答案

AFAIK 你试图混合两个答案:一个用于 @RequestScoped mbeans,另一个用于 @ViewScoped mbeans。如果您看到您发布的第一个链接,BalusC 表示您不必在 @ManagedProperty mbeans 中包含 @ViewScoped ,如 ViewParam vs @ManagedProperty(value = “#{param.id})” 所示。

如果您无法通过 View 参数传递 serviceLocator,则必须找到另一种获取该值的方法(从 session 中保存/检索它)。

此外,请检查 BalusC 中的此信息,解释为什么可以在每个请求上重新创建 @ViewScoped mbean:




  • The benefits and pitfalls of @ViewScoped


  • 根据您的评论和编辑,您可以使用此处提供的代码访问 @ApplicationScoped mbean:
  • How to get application scope variable in jsf?

  • 这将是这一行:
    FacesContext.getCurrentInstance().getExternalContext()
        .getApplicationMap().get("serviceLocator");
    

    您必须使用该代码,因为显然 @ViewScoped bean 不能接受 @ManagedProperty 的注入(inject)。

    关于jsf - 管理属性(property)继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13218329/

    10-10 08:09