Spring 3 - 基于注解的 Bean 验证
Spring 3 - Annotation based Bean Validation
我正在构建 REST API。它由一个资源(@Controller)组成,即使其中一个必填字段不存在,它 returns 也会响应 204。
我正在使用 Spring 3.1,validation-api (1.1.0.Final) & Hibernate-validator(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" 时,不会抛出任何错误。我在这里错过了什么?
可能会向您的 "addUserData" 方法传递一个 bindingResult 对象,以便您可以测试和检索验证错误。
这是一个如何使用它的例子:Validation form input
您必须具备以下有关基础设施的信息
@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)
- 删除
UserData
的 @Component
(代表一种实体,对吗?)。请记住,对于 class 每个实例都是唯一的 和 由 Spring 管理的任何 bean
是 Singleton.
- 将错误消息放入
.properties
文件
@POST
、@Consumes
和 @Produces
注释从何而来?。他们不在 Spring API
补充 01 关于您的评论:
是的,你必须使用@EnableWebMVC
。它指示 Spring 在内部为 Web 环境创建一些特殊的 bean。参见 @EnableWebMVC API。注释很重要。即使是休息,我也使用该注释。
关于Rest注解,使用Spring注解。如@RequestMapping
和新的'variations'如@GetMapping
、@PostMapping
等。即注解包含produces
和consumes
属性。我从未见过您混合两组来自 Rest 的注释的方法。
加法02
WebMvcConfigurerAdapter
class 表示有关所有 Spring MVC
基础设施的 XML 配置文件
因此 XML
@EnableWebMvc
等价于<mvc:annotation-driven/>
- 关于验证应该是:
<mvc:annotation-driven validator="beanNameValidator" />
其中 validator
属性符合 .xsd
说:
Attribute : validator The bean name of the Validator that is to be
used to validate Controller model objects. This attribute is not
required, and only needs to be specified explicitly if a custom
Validator needs to be configured. If not specified, JSR-303
validation will be installed if a JSR-303 provider is present on the
classpath.
beanNameValidator
按照我的@Bean
好像应该是localValidatorFactoryBean
我最终使用了 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>
我正在构建 REST API。它由一个资源(@Controller)组成,即使其中一个必填字段不存在,它 returns 也会响应 204。
我正在使用 Spring 3.1,validation-api (1.1.0.Final) & Hibernate-validator(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" 时,不会抛出任何错误。我在这里错过了什么?
可能会向您的 "addUserData" 方法传递一个 bindingResult 对象,以便您可以测试和检索验证错误。 这是一个如何使用它的例子:Validation form input
您必须具备以下有关基础设施的信息
@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) - 删除
UserData
的@Component
(代表一种实体,对吗?)。请记住,对于 class 每个实例都是唯一的 和 由 Spring 管理的任何bean
是Singleton.
- 将错误消息放入
.properties
文件 @POST
、@Consumes
和@Produces
注释从何而来?。他们不在 Spring API
补充 01 关于您的评论:
是的,你必须使用
@EnableWebMVC
。它指示 Spring 在内部为 Web 环境创建一些特殊的 bean。参见 @EnableWebMVC API。注释很重要。即使是休息,我也使用该注释。关于Rest注解,使用Spring注解。如
@RequestMapping
和新的'variations'如@GetMapping
、@PostMapping
等。即注解包含produces
和consumes
属性。我从未见过您混合两组来自 Rest 的注释的方法。
加法02
WebMvcConfigurerAdapter
class 表示有关所有 Spring MVC
基础设施的 XML 配置文件
因此 XML
@EnableWebMvc
等价于<mvc:annotation-driven/>
- 关于验证应该是:
<mvc:annotation-driven validator="beanNameValidator" />
其中validator
属性符合.xsd
说:
Attribute : validator The bean name of the Validator that is to be used to validate Controller model objects. This attribute is not
required, and only needs to be specified explicitly if a custom Validator needs to be configured. If not specified, JSR-303 validation will be installed if a JSR-303 provider is present on the classpath.
beanNameValidator
按照我的@Bean
好像应该是localValidatorFactoryBean
我最终使用了 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>