托管属性继承 [英] Managed property inheritance

查看:81
本文介绍了托管属性继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My problem is similar to this issue. I have a BaseBean which currently has just a single property which is annotated as a @ManagedProperty.

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

However, when I access the getter of this inherited managed property in the action method a commandbutton, it returns null. I debugged and confirmed that the base bean constructr was called twice - once on page load and next on click of the button as already described in the mentioned link.

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

I followed the suggestions as mentioned the article's chosen answer as well as this post, but to no avail.

以下是我的代码:

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);
      }
   }
}

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

Why would the constructor be called again on form submit ??? :/

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

The getter returns null even in the checkUserExists() method which is called via ajax on the blur event of the userID field.

编辑:为ServiceLocator添加了代码.

EDIT : Added code for 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表示您不必在@ViewScoped mbean中包含@ManagedProperty,如.

AFAIK you're trying to mix two answers: one for @RequestScoped mbeans and other for @ViewScoped mbeans. If you see the first link you've posted, BalusC is saying that you don't have to have @ManagedProperty in @ViewScoped mbeans as shown in ViewParam vs @ManagedProperty(value = "#{param.id})".

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

If you can't pass the serviceLocator through a view param, you have to find another way to get that value (saving/retrieving it from session).

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

Also, check this info from BalusC explaining why the @ViewScoped mbean could be recreated on every request:

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

In a nutshell: the @ViewScoped breaks when any UIComponent is bound to the bean using binding attribute or when using JSTL or tags in the view. In both cases the bean will behave like a request scoped one. The first one is in my opinion a pretty major bug, the second one is only an extra excuse to get rid of the whole JSTL stuff in Facelets.

这与JSF 2.0问题1492相关.这是相关性的一部分: 这是部分状态保存的鸡/蛋问题.在应用delta状态之前,将执行该视图以填充视图 ,因此我们看到了您所描述的行为. 在这一点上,我看不到解决此用例的明确方法. 如果必须使用视图范围的绑定,则解决方法是将javax.faces.PARTIAL_STATE_SAVING设置为false.

This is related to JSF 2.0 issue 1492. Here's an extract of relevance: This is a chicken/egg issue with partial state saving. The view is executed to populate the view before delta state is applied, so we see the behavior you've described. At this point, I don't see a clear way to resolve this use case. The workaround, if you must use view-scoped bindings would be setting javax.faces.PARTIAL_STATE_SAVING to false.

来自

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

Based on your comment and edit, you can access to the @ApplicationScoped mbean by using the code provided here:

这将是一行:

FacesContext.getCurrentInstance().getExternalContext()
    .getApplicationMap().get("serviceLocator");

您必须使用该代码,因为显然@ViewScoped bean无法接受@ManagedProperty的注入.

You have to use that code since, apparently, the @ViewScoped bean can't accept injection by @ManagedProperty.

这篇关于托管属性继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆