jsf一次验证两个字段[重复]
Posted
技术标签:
【中文标题】jsf一次验证两个字段[重复]【英文标题】:jsf validate two fields in one time [duplicate] 【发布时间】:2011-03-29 12:48:06 【问题描述】:我可以用一个验证器验证两个相互依赖的字段吗?
<h:form>
<h:inputText value="#logRegBean.person.name" >
<f:validator validatorId="loginCorrectValidator" />
</h:inputText>
<h:inputSecret value="#logRegBean.person.password" />
<h:commandButton action="#logRegBean.login" />
</h:form>
我想在数据库中搜索用户,如果有用户,我会测试密码(在数据库中和输入的)是否匹配。但是我如何才能访问一个验证器中的密码字段呢?我试图通过createValueExpression()
评估另一个字段的值,但看起来我在那段时间无法访问该值,因为我总是得到空字符串。
【问题讨论】:
【参考方案1】:你能做的最好的事情是通过UIViewRoot#findComponent()
在validate()
方法中获取另一个UIInput
组件,然后通过UIInput#getSubmittedValue()
确定提交的值(当它发生时之后组件树中当前经过验证的组件)或UIInput#getValue()
(当它出现在当前组件之前,因此已经经过验证)。
例如
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
UIInput otherInput = (UIInput) context.getViewRoot().findComponent("clientId");
String otherValue = (String) otherInput.getSubmittedValue();
// ...
另见:
JSF doesn't support cross-field validation, is there a workaround?【讨论】:
我也有同样的问题。我在我的代码中添加了示例代码。但是我得到了空指针异常。你能告诉我为什么吗? @Kayser:通常,当代码尝试访问/调用实际上是null
的引用时,您会得到它。另见docs.oracle.com/javase/7/docs/api/java/lang/…
DateIntervalValidator 不能为空 public void validate(FacesContext context, UIComponent component, Object value) UIInput fromComponent = (UIInput) context.getViewRoot().findComponent("from"); Date fromDate = (Date) fromComponent.getSubmittedValue();
<rich:calendar id="from"> <f:validator binding="#dateFieldValidator"/> <f:attribute name="fromDate" value="#msg['from']"/> </rich:calendar> <rich:calendar id="until"> <f:validator binding="#dateFieldValidator" /> <f:validator binding="#dateIntervalValidator"/> <f:attribute name="untilDate" value="#msg['until']"/> </rich:calendar>
@Kayser try findComponent("UIViewRoot#findComponent()
中的 ID 之前添加一个 :
。我认为,根据文档,它似乎遵循与 Xhtml ID 搜索相同的规则。【参考方案2】:
我认为 SeamFaces 的 s:validateForm
feature 可能正是您所需要的。 (Seam Faces 是一个非常有用的库,它为 JSF 带来了一些基于 CDI 的漂亮特性。)
【讨论】:
任何人都可以提供或链接有关在 Seam 停止并将验证转移到 beanvalidation.org 后s:validateForm
可用的位置的信息 [seamframework.org/Seam3]
@KarlRichter 据我所知,Seam 的继任者 Apache DeltaSpike 中还没有表单验证。目前,您仍然可以使用 Seam 的 s:validateForm
或 RichFaces 的 rich:graphValidator
。【参考方案3】:
JSF 中的验证机制旨在验证单个组件。 但是,在实践中,您通常需要确保相关组件具有合理的值,然后才能将值传播到模型中。 例如,要求用户在单个文本字段中输入日期不是一个好主意。 相反,您将使用三个不同的文本字段,分别表示日、月和年。
如果用户输入了非法日期,例如 2 月 30 日,您希望显示验证错误并防止非法数据进入模型。
诀窍是将验证器附加到最后一个组件。当它的验证器被调用时,前面的组件通过了验证并设置了它们的本地值。最后一个组件已通过转换,转换后的值作为验证方法的Object参数传递。
当然,您需要能够访问其他组件。您可以通过使用包含当前表单的所有组件的支持 bean 轻松实现该访问。只需将验证方法附加到支持 bean:
public class BackingBean
private int day;
private int month;
private int year;
private UIInput dayInput;
private UIInput monthInput;
private UIInput yearInput;
// PROPERTY: day
public int getDay() return day;
public void setDay(int newValue) day = newValue;
// PROPERTY: month
public int getMonth() return month;
public void setMonth(int newValue) month = newValue;
// PROPERTY: year
public int getYear() return year;
public void setYear(int newValue) year = newValue;
// PROPERTY: dayInput
public UIInput getDayInput() return dayInput;
public void setDayInput(UIInput newValue) dayInput = newValue;
// PROPERTY: monthInput
public UIInput getMonthInput() return monthInput;
public void setMonthInput(UIInput newValue) monthInput = newValue;
// PROPERTY: yearInput
public UIInput getYearInput() return yearInput;
public void setYearInput(UIInput newValue) yearInput = newValue;
public void validateDate(FacesContext context, UIComponent component, Object value)
int d = ((Integer) dayInput.getLocalValue()).intValue();
int m = ((Integer) monthInput.getLocalValue()).intValue();
int y = ((Integer) value).intValue();
if (!isValidDate(d, m, y))
throw new ValidatorException(new FacesMessage("Invalid Date"));
private static boolean isValidDate(int d, int m, int y)
//DO YOUR VALIDATION HERE
这是您的 JSP
<html>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<f:view>
<head></head>
<body>
<h:form>
<h:panelGrid columns="3">
<h:inputText value="#bb.day" binding="#bb.dayInput" size="2" required="true"/>
<h:inputText value="#bb.month" binding="#bb.monthInput" size="2" required="true"/>
<h:inputText value="#bb.year" binding="#bb.yearInput" size="4" required="true" validator="#bb.validateDate"/>
<h:message for="year" styleClass="errorMessage"/>
</h:panelGrid>
<h:commandButton value="Submit" action="submit"/>
</h:form>
</body>
</f:view>
</html>
参考: 核心 JavaServer™ 面孔 大卫·盖瑞,凯·霍斯曼
出版商:Addison Wesley 发布日期:2004 年 6 月 15 日 国际标准书号:0-13-146305-5
【讨论】:
如果您输入了一个有效的日期,例如 2017 年 2 月 28 日,然后将日期更改为 30 日,会发生什么?以上是关于jsf一次验证两个字段[重复]的主要内容,如果未能解决你的问题,请参考以下文章