Spring 3 - аннотация на основе проверки бобов

Я строю REST API. Он состоит из ресурса ( @Controller), который возвращает ответ 204, даже если одно из обязательных полей отсутствует.

Я использую Spring 3.1, validation-api (1.1.0.Final) и Hibernate-validator(4.3.0). Не уверен, что Hibernate-валидатор играет здесь какую-либо роль.

 <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.3.0.Final</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.validation</groupId>
                    <artifactId>validation-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

У меня есть контроллер пружины @Controller и бин с @Component

  @POST
        @Consumes(value = {MediaType.APPLICATION_JSON})
        @Produces(value = {MediaType.APPLICATION_JSON})
        @RequestMapping(method = RequestMethod.POST)
        public Response addUserData(@Valid @RequestBody UserData userDataRequest) throws ResourceException {
    ...
    }

Мой бин UserData имеет

  @Component 
    public class UserData {

        @NotNull(message = "user ID should not be null")
        @Min(value = 1, message = "user ID should not be empty")
        @Max(value = 20, message = "user ID should have length of more than 20")
        @Pattern(regexp="[A-Z][a-z]+", message = "Only Alphanumeric characters allowed")
        private String userId;

    }

Мои проверки не выполняются. Когда я не передаю "userId", ошибка не выдается. Что мне здесь не хватает?

3 ответа

Решение

В конечном итоге я использовал валидацию бобов Jersey вместо Spring. Это потому, что остальная часть моего кода использует Джерси в любом случае. Чтобы сделать это, я просто импортировал jar Valid Valid Jar и добавил небольшое изменение в web.xml. Проверки теперь работают.

Спасибо @Manual Джордан. Я буду приветствовать ваш ответ, так как он дал мне правильные подсказки.

<!--  jersey beanValidation  -->
       <init-param>
           <param-name>jersey.config.beanValidation.enableOutputValidationErrorEntity.server</param-name>
           <param-value>true</param-value>
       </init-param>

Вы должны иметь следующее об инфраструктуре

@EnableWebMvc
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    ...

    @Autowired
    private ValidatorConfig validatorConfig;

    ...

    @Override
    public Validator getValidator() {
        return validatorConfig.localValidatorFactoryBean();
    }

    ...

}

куда validatorConfig происходит от

@Configuration
public class ValidatorConfig {

    @Autowired
    private ReloadableResourceBundleMessageSource rrbms;

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean(){
        LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setValidationMessageSource(rrbms);
        return localValidatorFactoryBean;
    }

}

И, наконец, (я предлагаю вам рассмотреть возможность размещения сообщений об ошибках в .properties файл, такой как validation.properties как показано ниже)

@Configuration
public class MessageSourceConfig {

    @Bean(name="messageSource")
    public ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource() {
        ReloadableResourceBundleMessageSource resource = new ReloadableResourceBundleMessageSource();
        resource.setBasenames("classpath:/com/manuel/jordan/somethinga",
                              "classpath:/com/manuel/jordan/validation/validation");
        resource.setDefaultEncoding("UTF-8");
        return resource;
    }

}

Некоторые соображения или предложения:

  • менять @Valid в @Validated (см. API для @Validated)
  • Удалить @Component за UserData (что представляет собой вид сущности, верно?). Помните, что для этого класса каждый экземпляр уникален и любой bean управляется весной Singleton.
  • положить сообщения об ошибках в .properties файл
  • откуда приходят @POST, @Consumes а также @Produces Аннотации?. Их нет в Spring API

Дополнение 01 о вашем комментарии:

  • Да, вы должны использовать @EnableWebMVC, Это указывает на то, что Spring создаст несколько специальных bean-компонентов для веб-среды. Смотрите API @EnableWebMVC. Очень важно, что аннотация. Даже для отдыха я использую эту аннотацию.

  • О аннотациях Rest, используйте аннотации Spring. Такие как @RequestMapping и новые "вариации", такие как @GetMapping, @PostMapping и т. д., что аннотации содержат produces а также consumes атрибутов. Я никогда не видел вашего подхода к смешиванию двух наборов аннотаций от Rest.

Дополнение 02

WebMvcConfigurerAdapter класс представляет файл конфигурации XML обо всех Spring MVC инфраструктура

Поэтому для XML

  • @EnableWebMvc эквивалентно <mvc:annotation-driven/>
  • О валидации должно быть: <mvc:annotation-driven validator="beanNameValidator" /> где validator атрибут в соответствии с .xsd говорит:

Атрибут: validator Имя bean-компонента Validator, которое должно использоваться для проверки объектов модели Controller. Этот атрибут не
требуется, и должен быть указан явно, только если необходимо настроить пользовательский валидатор. Если не указано иное, проверка JSR-303 будет установлена, если в пути к классам присутствует поставщик JSR-303.

beanNameValidator в соответствии с моим @Bean кажется должно быть localValidatorFactoryBean

Может быть, переход к вашему методу addUserData, объект bindingResult, так что вы можете проверить и получить ошибки проверки. Вот пример того, как его использовать: Ввод формы проверки

Другие вопросы по тегам