Spring控制器没有调用@Valid

时间:2014-07-06 21:19:27

标签: java spring validation spring-mvc

我知道这个问题在这里被问了几次,但我找不到帮助我的答案

我正在尝试在我的控制器上使用@Valid注释,但是spring似乎不想对它做任何事情

这就是我在做的事情:

版本:

<org.springframework-version>4.0.5.RELEASE</org.springframework-version>
<hibernate-annotations-version>3.5.6-Final</hibernate-annotations-version>

我要验证的课程:

public class myclass{

private int                 id;

@NotEmpty
@Min(20)
private String              title;

@NotEmpty
private String              description;
}

控制器签名:

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ServerResponse<Integer> addSomeClass(@RequestBody @Valid myclass mymy) {

我也配置了

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

private @Value("${web.maxFileUploadSize}") int MAX_FILE_UPLOAD_SIZE;

public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    registry.addResourceHandler("/deployed/**").addResourceLocations("/deployed/");
}

@Bean
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver ret = new CommonsMultipartResolver();
    ret.setMaxUploadSize(MAX_FILE_UPLOAD_SIZE);
    return ret;
}

@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(){
    RequestMappingHandlerAdapter requestMappingHandlerAdapter = new RequestMappingHandlerAdapter();
    List<HttpMessageConverter<?>> messageConverters = new LinkedList<>();
    messageConverters.add(new MappingJackson2HttpMessageConverter());
    requestMappingHandlerAdapter.setMessageConverters(messageConverters);
    return requestMappingHandlerAdapter;
}

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

当我发送这个JSON时:

{"title":"","description":""}

没有任何反应,一切都在继续。

似乎无法找到答案。

更新

我已经有了:

<hibernate-validator-version>4.3.1.Final</hibernate-validator-version>

所以我把它更新为:5.1.1这就是我得到的

 Caused by: org.hibernate.cfg.beanvalidation.IntegrationException: Error activating Bean Validation integration
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:154)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:312)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:343)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:431)
at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:416)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 74 more
Caused by: java.lang.NoClassDefFoundError: javax/validation/ParameterNameProvider
at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:41)
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:269)
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:111)
at org.hibernate.cfg.beanvalidation.TypeSafeActivator.getValidatorFactory(TypeSafeActivator.java:459)
at org.hibernate.cfg.beanvalidation.TypeSafeActivator.activate(TypeSafeActivator.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:148)
... 82 more
Caused by: java.lang.ClassNotFoundException: javax.validation.ParameterNameProvider
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
... 92 more

所以我将validation-api更新为1.1.0.Final没有例外,但仍然没有验证

6 个答案:

答案 0 :(得分:3)

在(myclass mymy)之后尝试并在控制器签名上传递BindingResult,就像这样

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ServerResponse<Integer> addSomeClass(@RequestBody @Valid myclass mymy, BindingResult result) {

这通常对我有用,希望它也适合你.......!

答案 1 :(得分:1)

将Hibernate Validator依赖项添加到您的POM。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.1.Final</version>
</dependency>

答案 2 :(得分:1)

请提供有关项目设置的更多信息。你用的是什么弹簧版?你用spring mvc吗?如果是,请检查您是否有JSR-303 Validator in your classpath。最新的弹簧版本应自动检测并拾取它。

除此之外,您必须provide a LocalValidatorFactoryBean才能使验证工作。

@Configuration
public class ValidationConfiguration
{
    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean()
    {
        Locale.setDefault(Locale.ENGLISH);

        return new LocalValidatorFactoryBean();
    }
}

答案 3 :(得分:0)

我觉得有必要看看你的pom,或者至少是与这个问题相关的部分。我很确定这是依赖项之间的某些版本不匹配。根据你的春季版本,这是一个可能有用的组合:

<properties>
<spring.version>4.0.5.RELEASE</spring.version>
</properties>



<dependencies>

    <!-- Spring  dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- Hibernate Validator -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.3.1.Final</version>
    </dependency>

</dependencies>

===========编辑==========

只是想补充一点,看看控制器的更多实现细节也很有价值。如果您提供默认错误处理程序,那么您使用的方法可能会起作用(假设您具有正确的工件组合)。如果没有,你将不得不做@ Aph1ka建议的事情。以下是一些可能性:

@RequestMapping(value = "foo")
public class SomeController {
  @RequestMapping(method = RequestMethod.POST)
  @ResponseBody
  public ServerResponse<Integer> addSomeClass(@RequestBody @Valid myclass mymy) {
        ....
  }

  @ExceptionHandler
  @ResponseBody
  @ResponseStatus(value = HttpStatus.BAD_REQUEST)
  public Error handleException(MethodArgumentNotValidException exception) {
      return new ApiErrors(exception.getBindingResult());
  }

}

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ServerResponse<Integer> addSomeClass(@RequestBody @Valid myclass mymy, Errors errors) {
  if (errors.hasErrors()) {
     // return error some view e.g.
     return new ResponseEntity(new ApiErrors(errors), HttpStatus.BAD_REQUEST);
  }
  //....
}

或者,正如@ Aph1ka暗示:

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public ServerResponse<Integer> addSomeClass(@RequestBody @Valid myclass mymy, BindingResult result) {
  if (result.hasErrors()) {
    // return some error view
  }
  // ....
}

答案 4 :(得分:0)

测试控制器时遇到了类似的问题。添加时没有进行验证:

@InitBinder("multimediaParams")

但没有名字,就像这样:

@InitBinder

由于我们添加了第二个验证器,因此无法再使用最后一个选项。所以不要在测试中这样做:

Object handler = handlerMapping.getHandler(request).getHandler();
handlerAdapter.handle(request, response, handler);

我们现在手动添加了特定的验证器:

ConfigurableWebBindingInitializer webBindingInitializer = new ConfigurableWebBindingInitializer();
webBindingInitializer.setValidator(multimediaValidator);
handlerAdapter.setWebBindingInitializer(webBindingInitializer);

Object handler = handlerMapping.getHandler(request).getHandler();
handlerAdapter.handle(request, response, handler);

这样,验证将按预期再次进行。不漂亮,但有效。

答案 5 :(得分:-1)

  1. @NotEmpty是特定于Hibernate的,如果要通过JSR-303验证bean,则应使用@NotNull
  2. 您可以使用BindingResult进行验证,如@Aph1ka
  3. 所示
  4. 你可以看一下spring mvc showcase的工作实例 pom.xml
    validation