[英]JSF 2 inject Spring bean/service with @ManagedProperty and no xml
[英]Unable to inject JSF ViewScoped bean into Validator as ManagedProperty
我试图将JSF ViewScoped bean作为ManagedProperty注入到RequestScoped bean中,该bean实现了javax.faces.validator.Validator。 但是总是会注入ViewScoped bean的新副本。
ViewScoped Bean
@ViewScoped
@ManagedBean
public class Bean {
private Integer count = 1;
private String field2;
public String action(){
++count;
return null;
}
public String anotherAction(){
return null;
}
//getter and setter
}
验证器
@RequestScoped
@ManagedBean
public class SomeValidator implements Validator {
public void validate(FacesContext context, UIComponent comp, Object value)
throws ValidatorException {
//logging bean.getCount() is always one here. Even after calling ajax action a few times
}
@ManagedProperty(value = "#{bean}")
private Bean bean;
}
xhtml页面
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
</h:head>
<h:body>
<h:form>
<h:panelGroup layout="block" id="panel1">
<h:commandButton type="submit" value="Action" action="#{bean.action}">
<f:ajax render="panel1"></f:ajax>
</h:commandButton>
<h:outputText value="#{bean.count}"></h:outputText>
</h:panelGroup>
<h:panelGroup layout="block" id="panel2">
<h:inputText type="text" value="#{bean.field1}">
<f:validator binding="#{someValidator}" />
</h:inputText>
</h:panelGroup>
<h:commandButton type="submit" value="Another Action" action="#{bean.anotherAction}">
<f:ajax execute="panel2" render="panel2"></f:ajax>
</h:commandButton>
</h:form>
</h:body>
</html>
正如在代码中提到的,即使在调用ajax动作几次之后,当记录bean.getCount()时总是显示一个。
但是,如果我将ViewScoped更改为SessionScoped,则相同的方案也适用。 此外,如果我删除RequestScoped bean的Validator实现并在PostConstruct中使用记录器,则计数会按预期为每个ajax请求递增。
难道我做错了什么? 或者它应该如何工作? 提前致谢
这是因为在视图构建期间评估<f:validator>
binding
属性。 在那一刻,视图范围还不可用(它有意义,它仍然在忙于构建......),因此将创建一个全新的视图范围bean,它具有与请求范围bean相同的效果。 在即将到来的JSF 2.2中,这个鸡蛋问题将得到解决。
在那之前,如果你非常肯定你需要在validate()
方法中使用视图范围的bean(我宁愿寻找其他方法,比如<f:attribute>
,EJB,多字段验证器等),那么唯一的方法是在validate()
方法本身内以编程方式评估#{bean}
而不是通过@ManagedProperty
注入它。
您可以使用Application#evaluateExpressionGet()
:
Bean bean = context.getApplication().evaluateExpressionGet(context, "#{bean}", Bean.class);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.