f: convertDateTime не является строгим в сопоставлении с образцом? - PullRequest
1 голос
/ 28 сентября 2011

У меня есть f: convertDateTime с шаблоном мм / дд / гггг. Тем не менее, люди могут ввести 2/19/78, и это будет 0078, а не 1978 или 2078. Я хочу, чтобы люди вводили все 4 цифры.

Я пытался использовать валидатор regexPattern, но это жалуется, потому что ему нужна строка, а не объект Date. Кажется, что преобразователи запускаются первыми, а валидаторы проверяют преобразованное значение?

Полагаю, я мог бы написать собственный конвертер или валидатор, но мне кажется, что это такая простая вещь, что я делаю что-то не так.

Javadocs для конвертора говорят, что он строго соответствует шаблону, но я этого не вижу?

Есть идеи или предложения?

спасибо!

1 Ответ

3 голосов
/ 28 сентября 2011

Это строго по дням / месяцам, а не по годам.Вот выдержка из SimpleDateFormat javadoc , которую <f:convertDateTime> использует под обложками:

Для анализа, если количество букв шаблона больше 2,Год интерпретируется буквально, независимо от количества цифр.Таким образом, используя шаблон «MM / dd / yyyy», «01/11/12» анализирует до 11 января 12 г. н.э.По сути, этот должен был выдать 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...