Java 为什么f:validatedoubrerange只适用于@SessionScoped?
有人能解释一下为什么我的示例中的Foo在到达validatedoublrange类时总是为null吗?最终结果是验证程序的最小值始终为0。当在outputText元素中时,数字3在页面上显示得很好。 如果我使beanJava 为什么f:validatedoubrerange只适用于@SessionScoped?,java,validation,jsf,jakarta-ee,jsf-2,Java,Validation,Jsf,Jakarta Ee,Jsf 2,有人能解释一下为什么我的示例中的Foo在到达validatedoublrange类时总是为null吗?最终结果是验证程序的最小值始终为0。当在outputText元素中时,数字3在页面上显示得很好。 如果我使bean@SessionScoped而不是@ViewScoped 控制器: import java.io.Serializable; import java.math.BigDecimal; import javax.faces.bean.ManagedBean; import javax.
@SessionScoped
而不是@ViewScoped
控制器:
import java.io.Serializable;
import java.math.BigDecimal;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ViewScoped
@ManagedBean(name = "fooController")
public class FooController implements Serializable {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FooController.class);
private static final long serialVersionUID = 1L;
private Foo foo;
private BigDecimal amount;
private Long fooId;
public Long getFooId() {
return fooId;
}
public void setFooId(Long fooId) {
this.fooId = fooId;
this.foo = new Foo();
foo.setFooId(fooId);
foo.setMinAmount(Double.valueOf(3));
foo.setMaxAmount(Double.valueOf(10));
}
public Foo getFoo() {
return foo;
}
public void sendAmount() {
log.debug("sendAmount: " + amount);
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public static class Foo {
private Long fooId;
private Double minAmount;
private Double maxAmount;
public Foo() {
}
public void setFooId(Long fooId) {
this.fooId = fooId;
}
public void setMinAmount(Double minAmount) {
this.minAmount = minAmount;
}
public void setMaxAmount(Double maxAmount) {
this.maxAmount = maxAmount;
}
public Long getFooId() {
return fooId;
}
public Double getMaxAmount() {
return maxAmount;
}
public Double getMinAmount() {
return minAmount;
}
}
}
JSP:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
>
<f:metadata>
<f:viewParam name="fooId" value="#{fooController.fooId}" />
</f:metadata>
<h:form id="myForm">
<h:outputText value="This is correctly displayed: '#{fooController.foo.minAmount}'"/><br/>
<h:outputText value="My Input:" />
<h:inputText id="myInput"
value="#{fooController.amount}"
required="true"
>
<f:convertNumber maxFractionDigits="2"/>
<f:validateDoubleRange minimum="#{fooController.foo.minAmount}" maximum="80"/>
</h:inputText>
<h:message for="myInput"/>
<br/>
<h:commandButton id="myButton"
value="Save Amount"
action="#{fooController.sendAmount}"
>
</h:commandButton>
</h:form>
</ui:composition>
我在JBoss6.1上使用JSF2
如果你在那里@BalusC,这是我能想到的最简单的例子,和昨天的问题一样,只是,我希望,澄清了,更容易复制
--编辑,我应该添加fooId是通过view参数设置的,所以您需要在URL的末尾添加?fooId=3。我现在明白了为什么我昨天无法复制它。在我的游乐场环境中,我意外地将以下上下文参数设置为与默认值不同:
javax.faces.PARTIAL_STATE_保存
假的
这个问题与JSF有关。一个
的属性通过EL绑定到一个视图范围的bean属性,由于一个棘手的鸡蛋问题,它将隐式地重新创建整个bean,因为验证器是基于每个请求创建的,并且这些属性将在验证器的构造中传递
如果您不想禁用部分状态保存(非常合理),那么最好是自己在视图范围的托管bean中创建并保存验证器:
public Validator getValidator() {
return new DoubleRangeValidator(foo.getMaximum(), foo.getMinimum());
}
(注意,在getter中执行此操作是一种糟糕的设计,但是由于您在setter中准备foo
,而不是preRenderView
侦听器方法,因此没有其他方法,否则将在相同的侦听器方法中正确执行)
与
或者,为替换
的验证程序创建自定义验证程序:
与
更新:自Mojarra 2.1.18(2013年1月)以来,1492年的鸡蛋问题已得到解决。所以,如果你现在遇到了这个问题,那么你也可以考虑升级。哇,非常有帮助和有帮助。我想我可能是疯了。非常感谢。
package com.example;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.DoubleRangeValidator;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.ValidatorException;
@FacesValidator("bindableDoubleRangeValidator")
public class BindableDoubleRangeValidator extends DoubleRangeValidator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
setMinimum((Double) component.getAttributes().get("minimum"));
setMaximum((Double) component.getAttributes().get("maximum"));
super.validate(context, component, value);
}
}