1. 概述
Java Enterprise Edition (JEE) 7 提供了几个实用特性,比如用于验证用户输入、将值转换为适当 Java 数据类型的功能。
本教程将重点介绍转换器、监听器和验证器提供的这些特性。
2. 转换器
转换器允许我们将字符串输入值转换为 Java 数据类型。预定义的转换器位于 javax.faces.convert
包中,它们兼容任何 Java 数据类型,甚至像 Date
这样的标准类。
2.1 整数转换器
首先在托管 bean 中定义属性(作为 JSF 表单的后端):
private Integer age;
// getters and setters
然后在表单中使用 f:converter
标签创建组件:
<h:outputLabel value="Age:"/>
<h:inputText id="Age" value="#{convListVal.age}">
<f:converter converterId="javax.faces.Integer" />
</h:inputText>
<h:message for="Age" />
2.2 双精度转换器
类似地创建其他数值转换器(如 Double
转换器):
private Double average;
在视图中创建对应的 JSF 组件(注意通过命名约定映射字段):
<h:outputLabel value="Average:"/>
<h:inputText id="Average" value="#{convListVal.average}">
<f:converter converterId="javax.faces.Double" />
</h:inputText>
<h:message for="Average" />
⚠️ 重要提示:若要向用户提供反馈,必须包含 h:message
标签作为错误消息的占位符。
2.3 日期时间转换器
DateTime
转换器特别实用,因为它能验证日期/时间并格式化这些值。
首先在托管 bean 中声明字段:
private Date myDate;
// getters and setters
在视图中创建组件(必须使用模式输入日期,否则会报错):
<h:outputLabel value="Date:"/>
<h:inputText id="MyDate" value="#{convListVal.myDate}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
<h:message for="MyDate" />
<h:outputText value="#{convListVal.myDate}">
<f:convertDateTime dateStyle="full" locale="en"/>
</h:outputText>
✅ 这里我们将输入日期转换后,通过 h:outputText
以完整日期格式输出。
3. 监听器
监听器允许我们监控组件值的变化(例如文本框内容改变时)。
3.1 基本实现
在托管 bean 中定义属性:
private String name;
在视图中定义监听器:
<h:outputLabel value="Name:"/>
<h:inputText id="name" size="30" value="#{convListVal.name}">
<f:valueChangeListener type="com.baeldung.convListVal.MyListener" />
</h:inputText>
通过 f:valueChangeListener
指定监听器类,当触发时执行任务:
public class MyListener implements ValueChangeListener {
private static final Logger LOG = Logger.getLogger(MyListener.class.getName());
@Override
public void processValueChange(ValueChangeEvent event)
throws AbortProcessingException {
if (event.getNewValue() != null) {
LOG.log(Level.INFO, "\tNew Value:{0}", event.getNewValue());
}
}
}
❌ 踩坑提醒:监听器类必须实现 ValueChangeListener
接口并重写 processValueChange()
方法。
4. 验证器
验证器用于验证 JSF 组件数据,JSF 提供了标准验证类来检查用户输入。
4.1 长度验证器
以下示例验证文本框输入长度:
首先在托管 bean 中创建字段:
private String surname;
在视图中创建组件:
<h:outputLabel value="surname" for="surname"/>
<h:panelGroup>
<h:inputText id="surname" value="#{convListVal.surname}">
<f:validateLength minimum="5" maximum="10"/>
</h:inputText>
<h:message for="surname" errorStyle="color:red" />
</h:panelGroup>
在 h:inputText
标签内嵌入验证器限制输入长度。JSF 预定义了多种标准验证器,用法类似。
5. 测试
我们将使用 Arquillian 结合 Drone、Graphene 和 Selenium WebDriver 进行功能测试。
5.1 部署配置
使用 ShrinkWrap 部署应用:
@Deployment(testable = false)
public static WebArchive createDeployment() {
return (ShrinkWrap.create(
WebArchive.class, "jee7.war").
addClasses(ConvListVal.class, MyListener.class)).
addAsWebResource(new File(WEBAPP_SRC, "ConvListVal.xhtml")).
addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
5.2 错误消息测试
验证各组件错误消息确保应用正常工作:
@Test
@RunAsClient
public void givenAge_whenAgeInvalid_thenErrorMessage() throws Exception {
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
ageInput.sendKeys("stringage");
guardHttp(sendButton).click();
assertTrue("Show Age error message",
browser.findElements(By.id("myForm:ageError")).size() > 0);
}
类似测试需对每个组件执行。
6. 总结
本教程实现了 JEE7 提供的转换器、监听器和验证器功能。关键要点:
✅ 转换器:解决字符串到 Java 类型的转换问题
✅ 监听器:实时监控组件值变化
✅ 验证器:确保输入数据符合业务规则
❌ 常见陷阱:忘记添加 h:message
标签会导致错误信息不显示
完整代码可在 GitHub 获取。