f:convertDateTime在模式匹配中不严格?

时间:2011-09-28 15:36:23

标签: jsf-2

我有一个f:convertDateTime,模式为mm / dd / yyyy。然而,人们能够进入2/19/78并且它将是0078而不是1978或2078.我想强迫人们输入所有4位数。

我尝试使用regexPattern验证器,但这是抱怨,因为它想要一个字符串而不是Date对象。似乎转换器首先激活,验证器验证转换后的值?

我想我可以写一个自定义转换器或验证器,但这看起来很简单,我认为我做错了。

转换器的javadocs表示严格匹配模式,但我没有看到它?

有任何想法或建议吗?

谢谢!

1 个答案:

答案 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>