在Java中验证类数据(bean)并不是一个新话题,但它在这里也很重要,我将结合各个方面:在JSR-303中进行数据验证,我将展示如何仅在Java和Spring中执行此操作,以及如何在标准应用程序和Web上执行此操作。
内容:中的数据验证(JSR-303)
- 标准的Java应用程序
- 使用Spring
- Java +春季协会
- 春季MVC
在标准Java应用程序中进行验证
为了检查对象,使用在类的字段上的注释,即 声明模型。 注释已经准备就绪:
Null ,@DecimalMin,@Digits, Pattern , Email等
,您也可以自己制作。 所以有一个类(bean)
import javax.validation.constraints.Digits; import javax.validation.constraints.Size; public class Person { @Size(min=2, max=50) private String Name; @Digits(integer=3, fraction=0, message = " 3- ") @PersonAgeConstraint private Integer age; public Person(String name, Integer age) { Name = name; this.age = age; } }
在此示例中,
Size和@Digits准备好注解,以及@PersonAgeConstraint自己。 如何制作自己的:
-准备注释
@Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=PersonAgeConstraintValidator.class) public @interface PersonAgeConstraint { String message() default "{value.negative}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
在消息()中,从消息的资源文件(ValidationMessages.properties)中指定键(value.negative)
value.negative =负值
类的设计和实现-PersonAgeConstraintValidator.class
public class PersonAgeConstraintValidator implements ConstraintValidator<PersonAgeConstraint, Integer> { @Override public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) { return age > 0; } }
我自己的注释已准备就绪,我们将其添加到字段中,并且已经可以进行检查,所有带有注释的字段将通过相应的规则进行检查。
import javax.validation.Validator; public class DemoJValidationApplicationTests {
控制台结果
3-
通常,可以在消息文件中指定标准注释的消息:
AnnotationName.entity.fieldname=
项目结构

pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>DemoJSRvalidation</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>DemoJSRvalidation</name> <description>Demo project for Spring Boot JSR-303 validation</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
分阶段验证。 对于Class <?> [] Groups(),您可以指定可以对它们进行分组的类的类型,限制检查的列表,即 用作过滤器。 因此,可以分阶段进行验证:1)例如,出于健康原因,我们将对某人的检查分为两部分,然后是专业数据。 我们将准备两个注释
HealthConstraint和ProfessionalConstraint及其实现。 首先,我们检查对健康的依从性,然后通过健康检查专业数据。
一个例子:
public class Person { @HealthConstraint(groups = Health.class) private Documents healthDocuments; @ProfessionalConstraint(groups = Professional.class) private Documents ProfessionalDocuments;
HealthConstraint注释示例
@Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=HealthConstraintValidator.class) public @interface HealthConstraint { String message() default "{health.documents}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
HealthConstraintValidator实现示例
public class HealthConstraintValidator implements ConstraintValidator<HealthConstraint, Documents> { @Override public boolean isValid(Documents documents, ConstraintValidatorContext constraintValidatorContext) { return documents.contains(" 1"); } }
对于ProfessionalConstraint,一切都一样
下一步检查像这样:
@Test public void healthAndProfessionalValidators() { final Person person = new Person(" ", 45); person.setHealthDocuments(new Documents(Arrays.asList(" 1", " 3"))); person.setProfessionalDocuments(new Documents(Arrays.asList(" 1", " 4")));
例如,当我们从文件,Web服务和其他来源加载数据时,需要进行此类检查。
课程文件 public class Documents { private List<String> tests = new ArrayList(); public Documents(List<String> tests) { this.tests.addAll(tests); } public boolean contains(String test) { return this.tests.contains(test); } }
使用Spring验证
Spring还具有自己的Validator接口。
(org.springframework.validation.Validator)
如在Java中
(javax.validation.Validator)
而正是它的实现验证了数据。 这不再是一种声明式方法,而是具有自己的灵活性和可扩展性。 对于同一个垃圾箱,我将进行相同的年龄检查。
通过覆盖这两种方法,我们验证了
@Service public class PersonValidator implements Validator { @Override public boolean supports(Class<?> aClass) { return Person.class.equals(aClass); } @Override public void validate(Object obj, Errors errors) { Person p = (Person) obj; if (p.getAge() < 0) { errors.rejectValue("age", "value.negative"); } } }
value.negative-也是消息文件中的键,
public boolean supports
决定了所支持类的类型。
通过DataBinder启动验证
一个例子:
@RunWith(SpringRunner.class) @SpringBootTest public class DemoJValidationApplicationTests {
将执行为Person类实现org.springframework.validation.Validator的所有检查。
您还可以添加几个验证器dataBinder.addValidators,可以组成规则的组合(从一个规则调用,从另一个规则调用),例如:
public class OtherValidator implements Validator { @Override public boolean supports(Class<?> aClass) { return Person.class.equals(aClass); } @Override public void validate(Object obj, Errors errors) {
出于某种原因,我希望Spring也将执行注释中指示的检查,但是不,此调用必须独立完成。
项目结构

pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>DemoJSRvalidation</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>DemoJSRvalidation</name> <description>Demo project for Spring Boot JSR-303 validation</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Java和Spring
显然,我想在数据验证中使用两种方法-Java和Spring,您可以将它们组合在一起,即将javax.validation.Validator调用添加到Spring validateator。
例子
import javax.validation.Validator; @Service public class PersonValidator implements org.springframework.validation.Validator {
使用spring,我们进行注入
javax.validation.Validator
@Autowired
private Validator validator;
进一步关于方法
public void validate(Object obj, Errors errors)
在Java上执行声明性检查,然后在spring org.springframework.validation.Validator上对Person类执行所有检查。
我们还在春季进行验证
@Test public void testValidators() { final Person person = new Person("", -4500); final DataBinder dataBinder = new DataBinder(person); dataBinder.addValidators(personValidator); dataBinder.validate(); if (dataBinder.getBindingResult().hasErrors()) { dataBinder.getBindingResult().getAllErrors()
现在,在集合中将检查Person的java和spring批注(org.springframework.validation.Validator)
控制台输出
()
3- ()
(spring)
项目结构

春季MVC
当然,现在所有这些都可以在Web应用程序中应用。
我们将Controller,jsp页面添加到项目中(顺便说一下,这里可能还有其他选项,例如,使用freeMarker生成页面等),css样式,pom依赖项。 因此,为了
1)MVC控制器
import org.springframework.validation.Validator; @Controller public class DemoJValidationController { @Autowired @Qualifier("personValidator")
在这里与弹簧注入连接的PersonValidator
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
将PersonValidator设置为initBinder
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(personValidator);
}
@Valid
批注触发验证
在这种情况下,将仅执行弹簧检查,而声明式检查将被忽略。
如果从代码中删除
@InitBinder
protected void initBinder(WebDataBinder binder)
相反,将执行所有声明性检查,而spring将被忽略。
要完成所有声明式和弹簧式检查,您可以执行以下操作:
删除@InitBinder,保留注入
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
并手动添加弹簧检查电话
// spring validate
personValidator.validate(person, bindingResult);
这是代码:
@Controller public class DemoJValidationController { @Autowired @Qualifier("personValidator")
即 春季的其他检查将添加到bindingResult :-)中,这就是我想要的!
jsp和模型中的数据绑定由属性
modelAttribute="person"
。在示例中,连接了SpringMVC的Form Tag Library。
该示例的其余资源为:
DemoJValidationApplication @SpringBootApplication @ImportResource("classpath:configuration.xml") public class DemoJValidationApplication { public static void main(String[] args) { SpringApplication.run(DemoJValidationApplication.class, args); } }
弹簧配置
configuration.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/c" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:message"/> <property name="defaultEncoding" value="UTF-8"/> </bean> <mvc:annotation-driven/> <mvc:resources mapping="/resources/**" location="classpath:/META-INF/resources/"/> </beans>
personEdit.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <link href="<c:url value="/resources/my.css" />" rel="stylesheet"> <title>Person</title> </head> <body> <h3> Enter Person. </h3> <form:form method="POST" modelAttribute="person" action="save"> <div> Name: <form:input path="name"/> <form:errors path="name" cssClass="error"/> </div> <div> Age: <form:input path="age"/> <form:errors path="age" cssClass="error"/> </div> <button type="submit">Registration</button> </form:form> </body> </html>
saveSuccess.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <link href="<c:url value="/resources/my.css" />" rel="stylesheet"> <title>Person Saved Successfully</title> </head> <body> <h3> Person Saved Successfully. </h3> <form:form method="POST" modelAttribute="person" action="edit"> <div> ${name} </div> <div> ${age} </div> <button type="submit">Edit</button> </form:form> </body> </html>
my.css span.error { color: red; } form div{ margin: 5px; }
pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>DemoJSRvalidation</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>DemoJSRvalidation</name> <description>Demo project for Spring Boot JSR-303 validation</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.1.0.Final</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
项目结构

申请工作

用料
Bean验证规范