Spring 3 - 基于注释的Bean验证

时间:2016-10-03 23:09:45

标签: java spring rest validation spring-bean

我正在构建REST API。它由一个Resource(@Controller)组成,即使其中一个必填字段不存在,它也会返回一个响应204。

我正在使用Spring 3.1,validation-api(1.1.0.Final)& Hibernate的验证器(4.3.0)。不确定Hibernate-validator是否在此处扮演任何角色。

 <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>

我有一个Spring控制器@Controller和一个带@Component

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

3 个答案:

答案 0 :(得分: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)
  • 删除@Component的{​​{1}}(代表一种实体吗?)。请记住,对于该类,每个实例都是唯一的由Spring管理的任何UserData bean
  • 将错误消息放入Singleton.文件
  • 从何处.properties@POST@Consumes注释?它们不在Spring API中

添加01 关于您的评论:

  • 是的,您必须使用@Produces。它表明Spring在内部为Web环境创建了一些特殊的bean。请参阅@EnableWebMVC API。注释非常重要。即使是休息,我也会使用该注释。

  • 关于Rest注释,使用Spring注释。例如@EnableWebMVC和新的'变体',例如@RequestMapping@GetMapping等。这些注释包含@PostMappingproduces属性。我从未见过你从Rest中混合两组注释的方法。

添加02

consumes类表示有关所有WebMvcConfigurerAdapter基础架构

的XML配置文件

因此对于XML

  • Spring MVC相当于@EnableWebMvc
  • 关于验证,应该是<mvc:annotation-driven/>,其中<mvc:annotation-driven validator="beanNameValidator" />属性与validator相符:
  

属性:validator要成为的Validator的bean名称   用于验证Controller模型对象。此属性不是
  必需,并且只需要在自定义时明确指定   需要配置Validator。如果没有指定,JSR-303   如果JSR-303提供程序存在,则将安装验证   类路径。

.xsd根据我的beanNameValidator 似乎应为@Bean

答案 1 :(得分:1)

我最终最终使用了Jersey Bean Validation而不是Spring。这是因为我的其余代码仍在使用Jersey。为了完成这项工作,我刚刚导入了Jersey Bean Validation jar并对web.xml添加了一些小改动。验证现在正在运行。

谢谢@Manual Jordan。我会回答你的答案,因为它给了我正确的线索。

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

答案 2 :(得分:0)

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