Проверка Spring JSR303/349 без @Validated

Я создаю POJO из схемы json, используя jsonschema2pojo. Я хочу использовать материал проверки bean-компонентов jsr303/349. Я добавил необходимые элементы в путь к классам, добавил необходимые компоненты для запуска проверки, однако jsonschema2pojo не добавляет @org.springframework.validation.annotation.Validated к сгенерированным классам, поэтому проверка не запускается, когда запрос поступает в мое приложение весенней загрузки.

Я смог убедиться, что мой валидатор настроен правильно, написав такой пустой класс и изменив тип @RequestBody на новый тип:

@Validated
class SomeClass extends SomeGeneratedClass {

}

Когда я сделал это, проверка работает, как и ожидалось. Тем не менее, мы смотрим на десятки, если не на сотню или более этих объектов расширения, и наличие множества из них является воплощением сырого (IE, а не DRY) кода, и поэтому это далеко не идеальное решение.

Итак, мой вопрос: есть ли способ инициировать проверку bean-компонентов весной при входящем запросе, если рассматриваемый объект не аннотирован с помощью @Validated? Обратите внимание, что jsonschema2pojo в настоящее время не имеет зависимости от Spring, и я считаю маловероятным, что автор примет запрос на вытягивание, который добавляет ее.

-- Напишите, если это полезно

Пример схемы JSON:

{
  "type": "object",
  "properties": {
    "userIds": {
      "type": "array",
      "items": { "type": "string" },
      "minSize": 1
    }
  },
  "additionalProperties": false,
  "required": ["userIds"]
}

Сгенерированный класс:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "userIds"
})
public class ExampleSchema {

    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("userIds")
    @Valid
    @NotNull
    private List<String> userIds = new ArrayList<String>();

    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("userIds")
    public List<String> getUserIds() {
        return userIds;
    }

    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("userIds")
    public void setUserIds(List<String> userIds) {
        this.userIds = userIds;
    }

    public ExampleSchema withUserIds(List<String> userIds) {
        this.userIds = userIds;
        return this;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(userIds).toHashCode();
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if ((other instanceof ExampleSchema) == false) {
            return false;
        }
        ExampleSchema rhs = ((ExampleSchema) other);
        return new EqualsBuilder().append(userIds, rhs.userIds).isEquals();
    }
}

Настройка bean-компонента проверки в моем WebConfig:

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor(LocalValidatorFactoryBean validator) {
        final MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator);

        return methodValidationPostProcessor;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }

И мой метод контроллера:

@RequestMapping(value = "", method = RequestMethod.POST)
public void postExample(@RequestBody @Valid ExampleSchema example) {
    //Perform actions on validated object
}

person StormeHawke    schedule 27.04.2017    source источник
comment
Хммм, я думаю, что «@validated» не требуется для объекта. Вы можете использовать его как в своем postExample. Вам нужно использовать «@valid» или «@validated», если у вас есть свойства, ссылающиеся на объект, который также необходимо проверить. В этом случае вам необходимо аннотировать свойство.   -  person reos    schedule 27.04.2017
comment
Мой объект не проверяется, если я не расширил его с помощью класса, на котором есть @Validated.   -  person StormeHawke    schedule 27.04.2017
comment
Также вы заметите, что в сгенерированном классе выше уже есть аннотация @Valid для свойства.   -  person StormeHawke    schedule 27.04.2017
comment
Какую версию Spring boot вы используете? Вы пробовали без пользовательского валидатора?   -  person reos    schedule 27.04.2017
comment
Я не использую пользовательский валидатор. Весенняя загрузка 1.5.2.РЕЛИЗ   -  person StormeHawke    schedule 27.04.2017
comment
Как работает json для вашего примера? Что не проходит аттестацию?   -  person reos    schedule 27.04.2017
comment
Это не подтверждает ничего из этого. Мой тестовый пример отправляет нулевой массив userId (через почтальона).   -  person StormeHawke    schedule 27.04.2017
comment
Пожалуйста, добавьте json, который вы используете.   -  person reos    schedule 27.04.2017
comment
Это уже есть в вопросе. Это сокращенно, но это то, что я использую   -  person StormeHawke    schedule 27.04.2017
comment
я не вижу json   -  person reos    schedule 27.04.2017
comment
{ тип: объект, свойства: { userIds: { тип: массив, элементы: { тип: строка }, minSize: 1 } }, дополнительные свойства: false, обязательные: [userIds] }   -  person StormeHawke    schedule 27.04.2017
comment
Это прямо под разделом -- Код, если это полезно, выделено жирным шрифтом выше.   -  person StormeHawke    schedule 27.04.2017
comment
Или вы имеете в виду json, который я отправляю? В этом случае {}   -  person StormeHawke    schedule 27.04.2017
comment
Я добавил ответ на вопрос.   -  person reos    schedule 27.04.2017


Ответы (3)


В вашем классе вы определяете и создаете экземпляр массива в одной строке.

private List<String> userIds = new ArrayList<String>();

Итак, когда Spring проверяет объект, список userIds не равен нулю.

Здесь у вас есть два варианта.

  1. Вы можете удалить экземпляр userIds.

    личный список идентификаторов пользователей;

  2. Вы можете изменить проверку. Вместо использования @NotNull вы можете использовать @Size(min=1)или вы можете использовать их оба. Также вы можете использовать @NotEmpty, но вам нужен валидатор гибернации.

person reos    schedule 27.04.2017
comment
ааа это имеет смысл. Просто нужно, чтобы jsonschema2pojo не инициализировал коллекции. Теперь, чтобы выяснить, почему мой minSize: 1 не генерирует соответствующую аннотацию. Спасибо! - person StormeHawke; 27.04.2017

Вы можете аннотировать Controller или Service с помощью @Validated вместо того, чтобы делать это для всех объектов, которые необходимо проверить, например:

@Validated
@Controller
public class Controller {

    @RequestMapping(value = "", method = RequestMethod.POST)
    public void postExample(@RequestBody @Valid ExampleSchema example){
       //Perform actions on validated object
    }
}
person Arpit Aggarwal    schedule 27.04.2017
comment
Я перепробовал все комбинации добавления @Validated, какие только мог придумать. Я попытался поместить его в контроллер, метод, даже добавить его рядом с @Valid на RequestBody и во всех комбинациях вышеперечисленного. Проверка по-прежнему не запускается - person StormeHawke; 27.04.2017

создайте initbinder в вашем контроллере следующим образом:

@Autowired
YourValidator validator;

@InitBinder()
protected void initBinder(WebDataBinder binder) {

    binder.setValidator(validador);

}

И в вашей конечной точке

public OrdenServicioTo guardarOrden(@ModelAttribute("dto")@Validated @RequestBody Object dto)
{
    ///YOurCode
}
person Chay    schedule 27.04.2017