我有一个f:convertDateTime,模式为mm / dd / yyyy。然而,人们能够进入2/19/78并且它将是0078而不是1978或2078.我想强迫人们输入所有4位数。
我尝试使用regexPattern验证器,但这是抱怨,因为它想要一个字符串而不是Date对象。似乎转换器首先激活,验证器验证转换后的值?
我想我可以写一个自定义转换器或验证器,但这看起来很简单,我认为我做错了。
转换器的javadocs表示严格匹配模式,但我没有看到它?
有任何想法或建议吗?
谢谢!
答案 0 :(得分:3)
只有几天或几个月才会严格,而不是多年。以下是SimpleDateFormat
javadoc <f:convertDateTime>
正在使用的相关摘录:
对于解析,如果模式字母的数量大于2,则无论数字位数如何,都按字面解释年份。所以使用“MM / dd / yyyy”模式,“01/11/12”解析到公元12年1月11日
设计确实无法在转换器之前触发验证器。本质上,这个应该抛出一个ConverterException
因为输入格式不正确。我创建了一个自定义转换器,可以预先验证模式。像这样:
@FacesConverter("validatingPatternDateTimeConverter")
public class ValidatingPatternDateTimeConverter extends DateTimeConverter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
String regex = getMandatoryAttribute(component, "validateRegex");
String pattern = getMandatoryAttribute(component, "convertPattern");
if (value != null && !value.matches(regex)) {
throw new ConverterException(new FacesMessage(String.format("Invalid date, must be in pattern %s", pattern)));
}
setPattern(pattern);
return super.getAsObject(context, component, value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
setPattern(getMandatoryAttribute(component, "convertPattern"));
return super.getAsString(context, component, value);
}
private String getMandatoryAttribute(UIComponent component, String name) {
String value = (String) component.getAttributes().get(name);
if (value == null || value.isEmpty()) {
throw new IllegalArgumentException(String.format("<f:attribute name=\"%s\"> is missing.", name));
}
return value;
}
}
使用如下:
<h:inputText value="#{bean.date}">
<f:converter converterId="validatingPatternDateTimeConverter" />
<f:attribute name="validateRegex" value="\d{1,2}/\d{1,2}/\d{4}" />
<f:attribute name="convertPattern" value="MM/dd/yyyy" />
</h:inputText>