Проверка Javax: нарушения ограничений для карты

Я использую Map для локализованных значений с локалью в качестве ключа и String в качестве значения. Для обязательных полей мне нужно проверить, установлены ли по крайней мере требуемые языковые стандарты или, по крайней мере, установлено какое-то значение. Я реализовал аннотацию проверки, которая будет использоваться в таких полях карты, и соответствующий валидатор. Проблема в том, как я могу сообщить об отсутствующем значении? Путь к свойству, который используется в пользовательском интерфейсе для привязки ошибок / значений полей, каждый раз ошибается:

// Domain object:
@LocalizationRequired
private Map<Locale, String> field;


// LocalizationRequiredValidator:
public boolean isValid(Map<Locale, String> map, ConstraintValidatorContext context) {
    if (requiredLocales.isEmpty()) {
        // Check that there exists any not null value
    } else {
        context.disableDefaultConstraintViolation();
        boolean valid = true;
        for (Locale requiredLocale : requiredLocales) { 
            if (map.get(requiredLocale) == null) { // e.g. fi
                valid = false;
                context.buildConstraintViolationWithTemplate("LocalizationRequired")
                // These end up in wrong property path:
                // .addNode(requiredLocale) 
                //    --> field.fi
                // .addNode("[" + requiredLocale + "]") 
                //    --> field.[fi]
                // .addNode(null).addNode(requiredLocale).inIterable() 
                //    --> field.fi
                // .addNode(null).addNode(null).inIterable().atKey(requiredLocale)
                //   --> field
                .addConstraintViolation();
            }
        }
        return valid;
    }
}

Правильный путь для этой ошибки - «field [fi]», но, похоже, я могу получить доступ только к индексированным вспомогательным свойствам. В этом случае индексируется сам объект. Я использую Hibernate Validator.


person Samppa Saarela    schedule 27.07.2012    source источник


Ответы (2)


Мне не удалось найти способ сообщить об ошибках для индексированных полей на уровне элемента. - Это не было учтено в спецификации?

Вот что я сделал:

Вместо Map я использовал «встраиваемый» bean-компонент с фактическими полями для всех поддерживаемых локалей (например, LocalizedString (String fi, String en и т. Д.). Затем сообщил о таких нарушениях:

context.buildConstraintViolationWithTemplate("LocalizationRequired")
.addNode(requiredLocale)
.addConstraintViolation();

В нашем случае это возможно, поскольку у нас есть предопределенный набор поддерживаемых языков, но он не масштабируется до индексированных полей с произвольными индексами.

Более того, Spring LocalValidatorFactoryBean или Hibernate Validator не поддерживает правильную проверку встраиваемых файлов. Поскольку один и тот же компонент используется в разных местах с разными требованиями к валидации, я не могу использовать @Valid с фактическими аннотациями валидации внутри самого компонента - по крайней мере, без поддержки групп валидации на @Valid.

Проблема с Spring LocalValidatorFactoryBean или Hibernate Validator заключается в том, что invalidValue из ConstraintViolation - это LocalizedString («поле») вместо значения сообщенного ошибочного вложенного поля («field.fi»). К счастью, это можно решить, переопределив LocalValidatorFactoryBean.processConstraintViolations, удалив эту «настраиваемую регистрацию FieldError с недопустимым значением из ConstraintViolation» и сообщив об ошибках просто с помощью

errors.rejectValue(field, errorCode, errorArgs, violation.getMessage());

Таким образом, Spring разрешает invalidValue, используя заданный field.

person Samppa Saarela    schedule 09.08.2012

Это довольно интересный вопрос. Прямо сейчас у меня нет времени самому проверять :(, но вот этот парень:

Проверка коллекции

Кажется, можно проверить коллекцию элементов. Итак, если вы переключитесь на коллекцию вместо карты (что должно быть довольно легко), например:

 class LocaleToString {
      private Locale locale;
      private String language;
 }

 @LocalizationRequired
 List<LocaleToString> locales;

Я думаю, ты должен добиться того, чего хочешь.

person Eugene    schedule 06.08.2012
comment
Разница - это путь, к которому привязаны фактические ошибки валидации. Проверка коллекции сообщает обо всех ошибках на уровне коллекции (локали), а не на уровне элемента (локали [1]). Я пытался получить более конкретные ошибки (для привязки Spring). У меня возникает довольно сильное ощущение, что такого рода варианты использования не были учтены в спецификации ... т.е. нужно было бы использовать bean-компонент вместо индексированного файла. - person Samppa Saarela; 09.08.2012