托管财产继承

Vru*_*ank 5 jsf inheritance jsf-2

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

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

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

以下是我的代码:

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

   public IServiceLocator getServiceLocator() {
      return serviceLocator;
   }

   public void setServiceLocator(IServiceLocator serviceLocator) {
      this.serviceLocator = serviceLocator;
   }
}
Run Code Online (Sandbox Code Playgroud)
@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);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

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

checkUserExists()即使在通过 ajax 对 userID 字段的模糊事件调用的方法中,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;
   }
}
Run Code Online (Sandbox Code Playgroud)

Lui*_*oza 1

AFAIK 您正在尝试混合两个答案:一个用于@RequestScopedmbean,另一个用于@ViewScopedmbean。如果您看到您发布的第一个链接,BalusC 表示您不必@ManagedProperty@ViewScopedmbean 中使用ViewParam vs @ManagedProperty(value = \xe2\x80\x9c#{param.id})\ xe2\x80\x9d

\n\n

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

\n\n

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

\n\n
\n

简而言之:当使用绑定属性将任何 UIComponent 绑定到 bean 或在视图中使用 JSTL 或标签时,@ViewScoped 会中断。在这两种情况下,bean 的行为都类似于请求范围的 bean。在我看来,第一个是一个相当大的错误,第二个只是摆脱 Facelets 中所有 JSTL 内容的额外借口。

\n\n

这与 JSF 2.0 问题 1492 相关。以下是相关摘录:\n 这是一个具有部分状态保存的先有鸡还是先有蛋的问题。在应用增量状态之前执行视图以填充视图,因此我们看到了您所描述的行为。\n 此时,我没有看到解决此用例的明确方法。\n 解决方法,如果必须使用视图范围的绑定,请将 javax.faces.PARTIAL_STATE_SAVING 设置为 false。

\n
\n\n

\n\n\n\n
\n\n

根据您的评论和编辑,您可以@ApplicationScoped使用此处提供的代码访问 mbean:

\n\n\n\n

这将是一行:

\n\n
FacesContext.getCurrentInstance().getExternalContext()\n    .getApplicationMap().get("serviceLocator");\n
Run Code Online (Sandbox Code Playgroud)\n\n

您必须使用该代码,因为显然该@ViewScopedbean 无法接受@ManagedProperty.

\n