التحقق من بيانات الصف (الفول) في جافا ليس موضوعًا جديدًا ، ولكنه أيضًا ذو صلة هنا وسأجمع بين جوانب مختلفة: التحقق من صحة البيانات في JSR-303 ، وسأوضح كيفية القيام بذلك بحتة في Java واستخدام Spring ، وكيفية القيام بذلك في تطبيق قياسي وعلى الويب.
المحتويات: التحقق من صحة البيانات (JSR-303) في
- تطبيق جافا القياسي
- باستخدام الربيع
- جمعية جافا + الربيع
- mvc الربيع
التحقق في تطبيق Java قياسي
للتحقق من الكائن ، يتم استخدام التعليقات التوضيحية في حقول الصف ، أي نموذج تعريفي. التعليقات التوضيحية جاهزة بالفعل:
Null ،DecimalMin ،Digits ، Pattern ، Email ، etc.
، ويمكنك أيضًا أن تصنع بنفسك. وهكذا هناك فئة (حبة)
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; } }
هنا في المثال
الحجم و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 {}; }
في الرسالة () ، حدد المفتاح (value.negative) من ملف المورد (ValidationMessages.properties) للرسالة
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=
هيكل المشروع

ملف بوم <?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>
التحقق المرحلي. بالنسبة للفئة <؟> [] المجموعات () ، يمكنك تحديد أنواع الفصول التي يمكنك من خلالها تجميعها ، وتحديد قائمة الشيكات ، أي استخدم كمرشح. وبالتالي ، يمكن إجراء التحقق على مراحل ، 1) على سبيل المثال ، نقسم فحص الشخص لأسباب صحية ، 2) ثم البيانات المهنية. سنقوم بإعداد شروحين
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")));
هذه الفحوصات ، على سبيل المثال ، مطلوبة عندما نقوم بتحميل البيانات من ملف وخدمة ويب ومصادر أخرى.
وثائق الفصل 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)
كما في جافا
(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 {
سيتم تنفيذ جميع عمليات التحقق التي نفذت 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) {
لسبب ما توقعت أن يقوم الربيع أيضًا بإجراء الفحوصات الموضحة في التعليقات التوضيحية ، ولكن لا ، يجب إجراء هذه المكالمة بشكل مستقل.
هيكل المشروع

ملف بوم <?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 ، يمكنك الجمع بينهما ، وهما إضافة javax.validation.Validator لاستدعاء Spring Validator.
مثال
import javax.validation.Validator; @Service public class PersonValidator implements org.springframework.validation.Validator {
باستخدام الربيع ، نقوم بحقن
javax.validation.Validator
@Autowired
private Validator validator;
مزيد من المعلومات عن طريقة
public void validate(Object obj, Errors errors)
قم بإجراء الفحوصات التصريحية على جافا ثم قم بإجراء جميع الفحوصات لفئة الشخص في الربيع org.springframework.validation.Validator.
نقوم أيضًا بإجراء التحقق خلال فصل الربيع
@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()
الآن في المجموعة ، ستكون هناك فحوصات ضد جافا سكريبت والتعليقات التوضيحية الربيعية (org.springframework.validation.Validator) للشخص
إخراج وحدة التحكم
()
3- ()
(spring)
هيكل المشروع

mvc الربيع
بالطبع ، الآن يمكن تطبيق كل هذا في تطبيق ويب.
نضيف وحدة التحكم ، صفحة jsp إلى المشروع (هنا ، بالمناسبة ، قد تكون هناك خيارات أخرى ، على سبيل المثال ، إنشاء صفحات باستخدام freeMarker ، وما إلى ذلك) ، نمط css ، تبعية pom. وهكذا بالترتيب
1) تحكم MVC
import org.springframework.validation.Validator; @Controller public class DemoJValidationController { @Autowired @Qualifier("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)
على العكس من ذلك ، سيتم تنفيذ جميع الشيكات التقريرية ، وسيتم تجاهل الربيع.
لإكمال جميع الشيكات ، التصريح والربيع ، يمكنك القيام بذلك:
إزالةInitBinder ، وترك الحقن
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
وإضافة مكالمة شيك الربيع يدويًا
// spring validate
personValidator.validate(person, bindingResult);
هذا هو الرمز:
@Controller public class DemoJValidationController { @Autowired @Qualifier("personValidator")
أي ستضاف الشيكات الإضافية من الربيع إلى ملزمResult :-) ، وهو ما أردت!
يتم تنفيذ ربط البيانات في jsp والنموذج بواسطة السمة -
modelAttribute="person"
في المثال ، مكتبة علامات نماذج SpringMVC متصلة.
الموارد المتبقية من هذا المثال هي:
DemoJValidationApplication @SpringBootApplication @ImportResource("classpath:configuration.xml") public class DemoJValidationApplication { public static void main(String[] args) { SpringApplication.run(DemoJValidationApplication.class, args); } }
تكوين الربيع
config.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; }
ملف بوم <?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>
هيكل المشروع

عمل التطبيق

المواد
مواصفات التحقق من الفول