2016-10-03 133 views
1

我正在构建一个REST API。它由一个资源(@Controller)组成,该资源即使在其中一个必填字段不存在时也会返回响应204。Spring 3 - 基于注释的Bean验证

我正在使用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 bean有

@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”时,不会抛出任何错误。我在这里错过了什么?

回答

1

我最终结束了使用泽西Bean验证,而不是春季。这是因为我的其他代码无论如何都是在使用Jersey。为了做到这一点,我只导入了Jersey Bean Validation jar,并在web.xml中添加了一些小改动。验证正在工作。

谢谢@手动约旦。我会提高你的答案,因为它给了我正确的线索。

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

也许传递给你的“addUserData”方法,一个bindingResult对象,所以你可以测试和检索验证错误。 这里是如何使用它的例子:Validation form input

+0

我会尽力的,但我不认为这就是问题,因为状态出来为204 @Valid应该认识到,用户id为空,然后回来用400更新的问题是相同的。顺便说一句,我已经使用了你粘贴到目前为止的确切链接。 – greengrassbluesky

+0

更新 - 当我添加BindingResult(即使我没有MVC类型的实现)时,我得到以下错误SEVERE:StandardWrapper.Throwable org.glassfish.jersey.server.model.ModelValidationException:应用程序资源模型的验证失败应用初始化。 [[致命]没有为public javax.ws.rs.core.Response类型的参数添加注入源add(UserData,BindingResult) – greengrassbluesky

2

您必须对基础设施

@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(请参阅@Validated
  • 的API中取出@ComponentUserData(即代表了一种实体对?)。请记住,对于该类每个实例是唯一 Spring所管理的任何beanSingleton.
  • 把错误信息在.properties文件
  • 从哪里来的@POST@Consumes@Produces注解?他们不是春API

加成01关于你的评论中:

  • 是的,你必须使用@EnableWebMVC。它指示Spring为Web环境内部创建一些特殊的Bean。请参阅@EnableWebMVC API。这个注释非常重要。即使对于休息我也使用该注释。

  • 关于Rest标注,请使用Spring标注。如@RequestMapping和新的“变体”,如@GetMapping,@PostMapping等。该注释包含producesconsumes属性。我从来没有见过你将混合来自Rest的两套注解混合在一起。

加成02

WebMvcConfigurerAdapter类代表所有的Spring MVC基础设施

因此XML的XML配置文件

  • @EnableWebMvc相当于<mvc:annotation-driven/>
  • 关于验证它应该是:<mvc:annotation-driven validator="beanNameValidator" />其中具有.xsd根据validator属性说:

属性:验证待 用来验证控制器模型对象的验证bean的名称。该属性不是
必需的,只有在需要配置自定义 Validator时才需要明确指定。如果未指定,则在类路径 上存在JSR-303提供程序时,将安装JSR-303 验证。

beanNameValidator与根据我@Bean似乎应该localValidatorFactoryBean

+0

感谢您提供详细的响应。你建议使用EnableWebMVC吗?即使我正在编写REST API?对于你从哪里开始,消费者注释来自哪里,我正在使用follwing- import javax.validation.Valid; import javax.validation.constraints。*; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; – greengrassbluesky

+0

请参阅'加法01'部分 –

+0

我无法使用WebMvcConfigurerAdapter,因为它是Spring 4.3的一部分。我坚持使用Spring 3.1。任何其他的选择? – greengrassbluesky