Memvalidasi data kelas (kacang) di java bukanlah topik baru, tetapi juga relevan di sini dan saya akan menggabungkan berbagai aspek: validasi data dalam JSR-303, saya akan menunjukkan bagaimana melakukan ini secara murni di Jawa dan menggunakan Spring, bagaimana melakukannya dalam aplikasi standar dan di Web.
Isi: Validasi Data (JSR-303) di
- aplikasi java standar
- menggunakan Spring
- Asosiasi Jawa + Musim Semi
- Musim semi mvc
Validasi dalam aplikasi Java standar
Untuk memeriksa objek, anotasi pada bidang kelas digunakan, yaitu model deklaratif. Anotasi sudah siap:
Null , @DecimalMin, @Digits, Pattern , Email , dll.
, dan Anda juga bisa membuatnya sendiri. Dan ada kelas (kacang)
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; } }
Di sini, dalam contoh
Ukuran dan @Digits siapkan anotasi, dan @PersonAgeConstraint sendiri. Cara membuat sendiri:
- siapkan anotasi
@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 {}; }
Dalam pesan (), tentukan kunci (value.negative) dari file sumber daya (ValidationMessages.properties) untuk pesan
value.negative = Nilai negatif
dan implementasi kelas verifikasi - PersonAgeConstraintValidator.class
public class PersonAgeConstraintValidator implements ConstraintValidator<PersonAgeConstraint, Integer> { @Override public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) { return age > 0; } }
Anotasi saya sendiri sudah siap, kami menambahkannya ke bidang dan sudah mungkin untuk memeriksa, semua bidang yang ada anotasi akan diperiksa oleh aturan yang sesuai.
import javax.validation.Validator; public class DemoJValidationApplicationTests {
Menghasilkan konsol
3-
Pesan untuk anotasi standar dapat ditentukan dalam file pesan, sebagai aturan:
AnnotationName.entity.fieldname=
Struktur proyek

file 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>
Verifikasi bertahap. Untuk Kelas <?> [] Grup (), Anda dapat menentukan jenis kelas yang digunakan untuk mengelompokkannya, membatasi daftar cek, mis. gunakan sebagai filter. Dengan demikian, verifikasi dapat dilakukan secara bertahap, 1) Misalnya, kami membagi pemeriksaan seseorang untuk alasan kesehatan, 2) dan kemudian data profesional. Kami akan menyiapkan dua anotasi
HealthConstraint dan ProfessionalConstraint dan implementasi untuk mereka. Pertama kita memeriksa kepatuhan dengan kesehatan dan kemudian jika melalui kesehatan, kita memeriksa data profesional.
Contoh:
public class Person { @HealthConstraint(groups = Health.class) private Documents healthDocuments; @ProfessionalConstraint(groups = Professional.class) private Documents ProfessionalDocuments;
Contoh penjelasan 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 {}; }
Contoh implementasi HealthConstraintValidator
public class HealthConstraintValidator implements ConstraintValidator<HealthConstraint, Documents> { @Override public boolean isValid(Documents documents, ConstraintValidatorContext constraintValidatorContext) { return documents.contains(" 1"); } }
untuk ProfessionalConstraint semuanya sama
Cek selanjutnya seperti ini:
@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")));
Pemeriksaan semacam itu, misalnya, diperlukan ketika kita memuat data dari file, layanan web, dan sumber lainnya.
Dokumen kelas 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); } }
Validasi menggunakan Spring
Spring juga memiliki antarmuka Validator sendiri.
(org.springframework.validation.Validator)
seperti di java
(javax.validation.Validator)
dan justru implementasinya yang memvalidasi data. Ini bukan lagi pendekatan deklaratif, tetapi memiliki fleksibilitas dan ekstensibilitas sendiri. Untuk tempat sampah yang sama, saya akan melakukan pemeriksaan usia yang sama.
Dengan mengganti kedua metode, kami memvalidasi
@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 - juga merupakan kunci dalam file pesan,
public boolean supports
menentukan jenis kelas yang didukung.
Verifikasi diluncurkan melalui DataBinder
Contoh:
@RunWith(SpringRunner.class) @SpringBootTest public class DemoJValidationApplicationTests {
Semua pemeriksaan yang mengimplementasikan org.springframework.validation.Validator untuk kelas Person akan dilakukan.
Anda juga dapat menambahkan beberapa validator, dataBinder.addValidators, Anda dapat membuat komposisi aturan (panggilan dari satu aturan, yang lain), misalnya:
public class OtherValidator implements Validator { @Override public boolean supports(Class<?> aClass) { return Person.class.equals(aClass); } @Override public void validate(Object obj, Errors errors) {
Untuk beberapa alasan saya berharap bahwa Spring juga akan melakukan pemeriksaan yang ditunjukkan dalam penjelasan, tetapi tidak, panggilan ini harus dilakukan secara independen.
Struktur proyek

file 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>
Jawa & Musim Semi
Jelas, saya ingin menggunakan dua pendekatan dalam verifikasi data - Java dan Spring, Anda dapat menggabungkan mereka, yaitu, tambahkan panggilan javax.validation.Validator ke
validator Spring.
Contoh
import javax.validation.Validator; @Service public class PersonValidator implements org.springframework.validation.Validator {
Dengan menggunakan pegas, kami melakukan injeksi
javax.validation.Validator
@Autowired
private Validator validator;
lebih lanjut tentang metode
public void validate(Object obj, Errors errors)
melakukan pemeriksaan deklaratif di java dan kemudian lakukan semua pemeriksaan untuk kelas Person di spring org.springframework.validation.Validator.
Kami juga menjalankan verifikasi melalui pegas
@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()
Sekarang dalam koleksi akan ada pemeriksaan terhadap anotasi java dan spring (org.springframework.validation.Validator) untuk Orang
Output konsol
()
3- ()
(spring)
Struktur proyek

Musim semi mvc
Tentu saja, sekarang semua ini bisa diterapkan dalam aplikasi web.
Kami menambahkan Controller, halaman jsp ke proyek (di sini, omong-omong, mungkin ada opsi lain, misalnya, menghasilkan halaman menggunakan freeMarker, dll.), Gaya css, ketergantungan pom. Dan demikianlah urutannya
1) Kontroler MVC
import org.springframework.validation.Validator; @Controller public class DemoJValidationController { @Autowired @Qualifier("personValidator")
Di sini dengan injeksi spring terhubung PersonValidator
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
atur PersonValidator ke initBinder
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(personValidator);
}
Validasi dipicu oleh anotasi
@Valid
Dalam hal ini, hanya pemeriksaan pegas yang akan dilakukan, pemeriksaan deklaratif akan diabaikan.
Jika dihapus dari kode
@InitBinder
protected void initBinder(WebDataBinder binder)
sebaliknya, semua pemeriksaan deklaratif akan dilakukan, dan pegas akan diabaikan.
Untuk menyelesaikan semua pemeriksaan, deklaratif dan pegas, Anda dapat melakukan ini:
Hapus @InitBinder, tinggalkan injeksi
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
dan tambahkan panggilan periksa pegas secara manual
// spring validate
personValidator.validate(person, bindingResult);
Ini kodenya:
@Controller public class DemoJValidationController { @Autowired @Qualifier("personValidator")
yaitu cek tambahan dari musim semi akan ditambahkan ke bindingResult :-), itulah yang saya inginkan!
Pengikatan data dalam jsp dan model dilakukan oleh atribut -
modelAttribute="person"
Dalam contoh ini, Pustaka Tag Formulir SpringMVC terhubung.
Sumber daya yang tersisa dari contoh ini adalah:
DemoJValidationApplication @SpringBootApplication @ImportResource("classpath:configuration.xml") public class DemoJValidationApplication { public static void main(String[] args) { SpringApplication.run(DemoJValidationApplication.class, args); } }
Konfigurasi pegas
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; }
file 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>
Struktur proyek

Pekerjaan aplikasi

Material
Spesifikasi validasi kacang