【问题标题】:f:convertDateTime not being strict in pattern match?f:convertDateTime 在模式匹配中不严格?
【发布时间】:2011-09-28 15:36:22
【问题描述】:

我有一个 f:convertDateTime,其模式为 mm/dd/yyyy。但是,人们可以输入 2/19/78,它将是 0078 而不是 1978 或 2078。我想强制人们输入所有 4 位数字。

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

我想我可以编写一个自定义转换器或验证器,但这似乎是一件如此简单的事情,我认为我做错了什么。

转换器的 javadocs 说它在匹配模式方面很严格,但我没有看到?

有什么想法或建议吗?

谢谢!

【问题讨论】:

    标签: jsf-2


    【解决方案1】:

    它只对几天/几个月严格,而不是对几年。以下是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>
    

    【讨论】:

      猜你喜欢
      • 2017-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 2014-07-09
      相关资源
      最近更新 更多