JSF验证深度解析:从内置验证器到自定义实现
这是文章《JSF验证示例教程 – 验证器标签,自定义验证器》的第1部分(共1部分)。
JSF验证模型定义了一组用于验证UI组件的标准类。JSF库定义了一组核心标签,这些标签对应于javax.faces.validator.Validator
的实现类。除了标准的错误消息外,验证模型还允许我们定义自定义验证。JSF中的验证可以分为命令式和声明式两种类型。
JSF 验证 – 声明式验证器
使用JSF标准验证器或Bean验证器触发的验证属于声明式类型。JSF标准验证器的示例包括长度验证器、必填验证器等。下面我们来看一个标准验证器的例子。创建一个名为mobile.xhtml
的文件。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
</h:head>
<h:body>
<h3>添加手机详情</h3>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel for="mname">手机名称:</h:outputLabel>
<h:inputText id="mname" required="true"
requiredMessage="手机名称为必填项"></h:inputText>
<br>
<br>
<h:outputLabel for="color">颜色:</h:outputLabel>
<h:inputText id="color" required="true"></h:inputText>
<br>
<br>
<h:outputLabel for="model">型号:</h:outputLabel>
<h:inputText id="model"></h:inputText>
<br>
<br>
<h:commandButton value="提交"></h:commandButton>
</h:panelGrid>
</h:form>
</h:body>
</html>
在此示例中,我们将required
属性设置为true
,这使得该字段成为必填项。对于“颜色”字段,将触发默认的“值是必需的”消息;而对于“手机名称”字段,由于在requiredMessage
属性中指定了消息,将触发用户定义的消息。运行应用程序,点击提交按钮,您将看到以下输出。
JSF 命令式验证
在某些情况下,标准验证消息可能不足以满足需求,有时可能需要更复杂的验证。通过命令式验证,用户可以实现这一点。
- 从Bean方法触发验证
- 在运行时在类中使用注解
@FacesValidator
从Bean方法中触发验证:在这种类型的验证中,我们在Bean中编写一个方法来验证UI组件,并通过输入文本标签的validator
属性在JSF页面中调用此方法。现在让我们看一个从Bean触发验证的例子。创建一个名为mob.xhtml
的文件。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
</h:head>
<h:body>
<h3>添加手机详情</h3>
<h:form>
<h:outputLabel for="mno">型号:</h:outputLabel>
<h:inputText id="mno" value="#{mobile.mno}" required="true" size="4"
disabled="#{mobile.mno}" validator="#{mobile.validateModelNo}">
</h:inputText>
<h:commandButton value="提交"></h:commandButton>
</h:form>
</h:body>
</html>
在这个页面中,我们在validator
标签属性中调用了Java Bean的validateModelNo
方法。创建Mobile.java
文件如下:
package com.Olivia.jsf.bean;
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
@ManagedBean
@SessionScoped
public class Mobile implements Serializable {
private static final long serialVersionUID = -7250065889869767422L;
// @NotNull(message="请输入型号")
private String mno;
public String getMno() {
return mno;
}
public void setMno(String mno) {
this.mno = mno;
}
public void validateModelNo(FacesContext context, UIComponent comp,
Object value) {
System.out.println("进入验证方法");
String mno = (String) value;
if (mno.length() < 4) {
((UIInput) comp).setValid(false);
FacesMessage message = new FacesMessage(
"型号的最小长度为4");
context.addMessage(comp.getClientId(context), message);
}
}
}
在这里,我们检查型号的长度,如果长度小于4,我们将指定消息为“型号的最小长度为4”。现在运行应用程序,将产生以下输出。
在Bean中使用@FacesValidator
– 自定义JSF验证器
在这种方法中,我们使用@FacesValidator
注解,为验证器指定名称,并通过覆盖validate
方法来实现验证器。创建一个名为mobvalidator.xhtml
的文件。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://xmlns.jcp.org/jsf/html"
xmlns:f="https://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<h:form>
<h3>使用Faces验证器进行验证</h3>
<h:outputLabel for="mno" value="型号: " />
<h:inputText id="mno" value="#{mobileValidator.mno}">
<f:validator validatorId="mobileValidator" />
</h:inputText>
<h:message for="mno" style="color:blue" />
<p></p>
<h:commandButton value="提交"></h:commandButton>
</h:form>
</h:body>
</html>
在这里,我们在标签的validatorId
属性中调用名为“mobileValidator”的自定义验证器。创建名为MobileValidator.java
的文件。
package com.Olivia.jsf.bean;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
@ManagedBean
@SessionScoped
@FacesValidator("mobileValidator")
public class MobileValidator implements Validator {
private String mno;
public String getMno() {
return mno;
}
public void setMno(String mno) {
this.mno = mno;
}
int maximumlength = 6;
public MobileValidator() {
}
@Override
public void validate(FacesContext fc, UIComponent uic, Object obj)
throws ValidatorException {
String model = (String) obj;
if (model.length() > 6) {
FacesMessage msg = new FacesMessage(
"最大长度为6,请在范围内输入值");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(msg);
}
}
}
在这里,我们覆盖了标准的validate
方法,并实现了自己的逻辑来验证输入字段。运行应用程序并查看以下输出。最后,下面的图片显示了项目结构。您可以从下面的链接下载该项目并进行试验以获取更多了解。