我的问题类似于这个 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:
从
根据您的评论和编辑,您可以使用此处提供的代码访问
@ApplicationScoped
mbean:这将是这一行:
FacesContext.getCurrentInstance().getExternalContext()
.getApplicationMap().get("serviceLocator");
您必须使用该代码,因为显然
@ViewScoped
bean 不能接受 @ManagedProperty
的注入(inject)。关于jsf - 管理属性(property)继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13218329/