1. Verifikasi parameter
Dalam pengembangan, Anda sering perlu menulis beberapa kode untuk verifikasi lapangan, seperti bidang yang tidak kosong, batas panjang bidang, verifikasi format kotak surat, dll. Saya pribadi merasa bahwa ada dua masalah saat menulis kode-kode ini yang tidak ada hubungannya dengan logika bisnis:
Hibernate Validator (Dokumen Resmi) menyediakan metode implementasi verifikasi yang relatif lengkap dan nyaman.
Paket Spring-Boot-Starter-Web memiliki paket hibernate-validator, dan tidak perlu merujuk pada ketergantungan validator hibernate.
2. Demo verifikasi validator hibernate
Mari pertama -tama lihat demo sederhana, menambahkan anotasi validator:
impor org.hibernate.validator.constraints.notblank; impor javax.validation.constraints.assertfalse; impor javax.validation.constraints.pattern;
@Getter@setter@noargsconstructorpublic kelas demomodel {@notblank (pesan = "Nama pengguna tidak dapat kosong") Private String username; @Notblank (pesan = "Usia tidak bisa kosong") @pattern (regexp = "^[0-9] {1,2} $", pesan = "usia salah") usia string pribadi; @AssertFalse (pesan = "harus false") private boolean isFalse; / *** Jika kosong, itu tidak akan diperiksa, dan jika tidak kosong, itu akan diperiksa*/ @pattern (regexp = "^[0-9] {4}-[0-9] {2}-[0-9] {2} $", pesan = "Tanggal lahir tidak benar") Ulang Tahun Privat;Verifikasi antarmuka pasca, BindingResult adalah kumpulan hasil yang gagal lulus verifikasi:
@RequestMapping("/demo2") public void demo2(@RequestBody @Valid DemoModel demo, BindingResult result){ if(result.hasErrors()){ for (ObjectError error : result.getAllErrors()) { System.out.println(error.getDefaultMessage()); }}} Parameter disahkan melalui permintaan pos :{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}
Hasil output:
Tanggal lahir tidak benar dan harus salah
Usia yang salah
Verifikasi parameter sangat nyaman. Jika anotasi + verifikasi di lapangan tidak dilewati, ia dapat menggantikan tulisan tangan dari banyak kode verifikasi pembatasan yang tidak kosong dan pembatasan. Di bawah ini kami memiliki pemahaman yang lebih dalam tentang cara memainkan verifikasi parameter.
3. Mode Verifikasi Hibernate
Pembaca yang cermat harus menemukan bahwa dalam contoh di atas, semua set yang gagal lulus verifikasi dikembalikan sekaligus. Biasanya, ketika bidang pertama tidak memenuhi persyaratan verifikasi secara berurutan, permintaan dapat ditolak secara langsung. Hibernate Validator memiliki dua mode verifikasi berikut:
1. Mode Normal (Mode ini default)
Mode normal (semua atribut akan diperiksa dan kemudian semua informasi kegagalan verifikasi akan dikembalikan)
2. Kegagalan cepat untuk kembali ke mode
Mode Pengembalian Kegagalan Cepat (kembali selama ada kegagalan verifikasi)
Dua metode konfigurasi mode verifikasi: (lihat dokumentasi resmi)
Failfast: Mode Pengembalian Gagal Cepat Benar Mode Normal Salah
ValidatorFactory validatorFactory = validation.byprovider (hibernatevalidator.class) .configure () .failfast (true) .buildvalidatorFactory (); Validator validator = validatorFactory.getValidator ();
dan (hibernate.validator.fail_fast: Mode pengembalian cepat gagal yang benar -benar false mode)
ValidatorFactory validatorFactory = validation.byprovider (hibernatevalidator.class) .configure () .addproperty ("hibernate.validator.fail_fast", "true") .buildvalidatorFactory (); Validator validator = validatorFactory.getValidator ();4. Dua jenis verifikasi hibernate
Konfigurasikan validator hibernate untuk mengembalikan mode ke kegagalan cepat:
@ConfigurationPublic kelas ValidatorConfiguration {@Bean Public Validator Validator () {validatorFactory validatorFactory = validation.byprovider (hibernateValidator.class) .fail_figure () .addProperty ("hibernate.validator.fail_fast". Validator validator = validatorFactory.getValidator (); validator pengembalian; }}1. Verifikasi Parameter Permintaan
Seperti dalam contoh dalam demo, saat memverifikasi parameter permintaan, tambahkan @valid antara demo demomodel @RequestBody, dan kemudian tambahkan BindindResult; Untuk beberapa parameter, Anda dapat menambahkan beberapa @valid dan BindingResult, seperti:
tes public void () ( @requestbody @valid demo demomodel, hasil pengikat result) tes public void () ( @requestbody @valid demomodel demo, Hasil BINDINGRESULT, @requestbody @Valid Demomodel Demo2, BindingResult Hasil2)
@RequestMapping("/demo2") public void demo2(@RequestBody @Valid DemoModel demo, BindingResult result){ if(result.hasErrors()){ for (ObjectError error : result.getAllErrors()) { System.out.println(error.getDefaultMessage()); }}}2. Dapatkan verifikasi parameter (verifikasi parameter @RequestParam)
Menggunakan metode memeriksa kacang, tidak ada cara untuk memeriksa konten RequestParam. Secara umum, saat memproses permintaan mendapatkan (atau lebih sedikit parameter), kode berikut akan digunakan:
@RequestMapping (value = "/demo3", Method = requestMethod.get) public void demo3 (@RequestParam (name = "grade", wajib = true) int grade,@requestParam (name = "classroom", wajib = true) int kelas) {System.println (grade + "," + classroom); }Menggunakan anotasi @valid untuk memberi anotasi parameter yang sesuai dengan RequestParam tidak valid. Diperlukan anotasi @Validated untuk membuat verifikasi berlaku. Seperti yang ditunjukkan di bawah ini:
A. Pada saat ini, Anda perlu menggunakan Bean of MethodValidationPostProcessor :
@Bean MethodValidationPostProcessor MetodeValidationPostProcessor () { / ** Default adalah mode normal, dan semua verifikasi akan dikembalikan tanpa melewati pengumpulan informasi* / return new MethodValidationPostProcessor (); } Atau Anda dapat mengatur validator untuk MethodValidationPostProcessor (karena validator tidak digunakan untuk verifikasi saat ini, konfigurasi validator tidak berfungsi)
@Bean MethodValidationPostProcessor MethodValidationPostProcessor () {MethodValidationPostProcessor postprocessor = MethodValidationPostProcessor baru (); / ** Atur Mode Validator ke Kegagalan Kegagalan Cepat*/ postprocessor.setValidator (validator ()); mengembalikan postprocessor; } @Bean validator validator () {validatorFactory validatorFactory = validation.byprovider (hibernatevalidator.class) .configure () .addproperty ("hibernate.validator.fail_fast", "true") .buildvalidatorFactory (); Validator validator = validatorFactory.getValidator (); validator pengembalian; }B. Tambahkan anotasi ke pengontrol di mana metode ini berada @validasi
@RequestMapping (" /validasi")@restcontroller@ValidatedPublic Class ValidationController { /** Jika hanya ada beberapa objek, cukup tulis parameter ke lapisan pengontrol dan kemudian verifikasi di lapisan pengontrol. */ @RequestMapping(value = "/demo3", method = RequestMethod.GET) public void demo3(@Range(min = 1, max = 9, message = "Grade can only be from 1-9") @RequestParam(name = "grade", required = true) int grade, @Min(value = 1, message = "Class minimum can only be 1") @Max(value = 99, message = "Class maximum can only be 99 ") @RequestParam (name =" classroom ", wajib = true) int classroom) {System.out.println (grade +", " + classroom); }}C. Kembali ke Prompt Informasi Verifikasi
Anda dapat melihat: Ketika verifikasi gagal, pengecualian Exception Exception Constrainviolation dilemparkan dan pengecualian tangkapan yang sama ditangani:
@ControllerAdvice @componentPublic kelas globalExceptionHandler {@ExceptionHandler @ResponseBody @ResponseStatus (httpstatus.bad_request) pegangan string publik (pengecualian validasi) {if exception dari ConsepionException) {ConseptException) {if exception = ConseptaintViolationEcception) {ConstraptionSception; Set <ConstraintViolation <? >> Pelanggaran = exs.getConstraintviolations (); for (ConstraintViolation <?> Item: pelanggaran) { / ** Cetak informasi yang gagal lulus verifikasi* / System.out.println (item.getMessage ()); }} mengembalikan "permintaan buruk,"; }}D. Verifikasi
Alamat Permintaan Layanan Browser: http: // localhost: 8080/validasi/demo3? Grade = 18 & classroom = 888
Informasi Output Ketika MethodValidationPostProcessor kembali tanpa mengkonfigurasi kegagalan cepat adalah sebagai berikut:
Nilai hanya bisa dari 1-9
Kelas maksimum hanya bisa 99
Ketika MethodValidationPostProcessor dikonfigurasi dengan pengembalian kegagalan cepat, informasi output adalah sebagai berikut:
Nilai hanya bisa dari 1-9
Alamat Permintaan Layanan Browser: http: // localhost: 8080/validasi/demo3? Grade = 0 & classroom = 0
Informasi Output Ketika MethodValidationPostProcessor kembali tanpa mengkonfigurasi kegagalan cepat adalah sebagai berikut:
Nilai hanya bisa dari 1-9
Kelas minimum hanya bisa 1
Ketika MethodValidationPostProcessor dikonfigurasi dengan pengembalian kegagalan cepat, informasi output adalah sebagai berikut:
Nilai hanya bisa dari 1-9
3. Verifikasi model
Model yang harus diverifikasi:
@DataPublic kelas demo2 {@length (min = 5, max = 17, message = "Panjang panjang antara [5,17]") panjang string pribadi; / ** @ukuran tidak dapat memverifikasi integer, cocok untuk string, koleksi, peta dan array*/ @size (min = 1, maks = 3, pesan = "ukuran antara [1,3]") usia string pribadi; @Range (min = 150, maks = 250, pesan = "Rentang adalah antara [150.250]") private int high; @Size (min = 3, maks = 5, pesan = "Ukuran daftar ada dalam [3,5]") Daftar Privat <String> Daftar;}Verifikasi model, semua verifikasi berikut dilewatkan:
@Autowired Private Validator Validator; @RequestMapping ("/Demo3") public void demo3 () {demo2 demo2 = new Demo2 (); demo2.setage ("111"); demo2.sethigh (150); demo2.setLength ("ABCDE"); demo2.setList (arraylist baru <string> () {{add ("111"); add ("222"); add ("333");}}); Set <ConceptViolation <demo2>> pelanggaran = validator.validate (demo2); for (ConstraintViolation <demo2> model: pelanggaran) {System.out.println (model.getMessage ()); }}4. Verifikasi kaskade objek
Objek berisi objek lain sebagai properti, dan tambahkan @valid ke properti untuk memverifikasi verifikasi di dalam objek sebagai properti: (Saat memverifikasi contoh demo2, Anda dapat memverifikasi bidang demo2)
@DataPublic Class Demo2 {@size (min = 3, max = 5, pesan = "Ukuran daftar ada dalam daftar <3,5]") Daftar Privat <String>; @Notnull @valid private demo3 demo3;} @datapublic class demo3 {@length (min = 5, maks = 17, pesan = "Panjang panjang antara [5,17]") string private extfield;}Verifikasi Cascade:
/ ** Bean dikonfigurasi dengan Fast Failure Return Bean*/ @Autowired Private Validator Validator; @RequestMapping ("/Demo3") public void demo3 () {demo2 demo2 = new Demo2 (); demo2.setList (arraylist baru <string> () {{add ("111"); add ("222"); add ("333");}}); Demo3 demo3 = demo3 baru (); demo3.setextfield ("22"); demo2.setDemo3 (demo3); Set <ConceptViolation <demo2>> pelanggaran = validator.validate (demo2); for (ConstraintViolation <demo2> model: pelanggaran) {System.out.println (model.getMessage ()); }}Bidang Extfield Demo3 dapat diperiksa.
5. Verifikasi Grup
Kesimpulan: Saat memverifikasi urutan pengelompokan, verifikasi dalam urutan pengelompokan yang ditentukan. Jika verifikasi sebelumnya gagal, pengelompokan selanjutnya tidak dapat diverifikasi.
Ada skenario di mana ketika informasi pengguna baru ditambahkan, tidak perlu memverifikasi userid (karena sistem dihasilkan); Saat memodifikasi, UserID perlu memverifikasi UserID, dan fungsi verifikasi grup dari pengguna ke validator dapat digunakan.
Setel validator ke mode verifikasi normal ("hibernate.validator.fail_fast", "false"), dan menggunakan verifikasi groupa, groupb dan model:
Groupa, groupb: antarmuka publik groupa {} antarmuka publik groupb {}Verifikasi Model: Orang
@DataPublic class Person {@notblank @range (min = 1, max = integer.max_value, message = "Harus lebih besar dari 0", grup = {groupa.class}) / ** ID pengguna* / private integer userid; @Notblank @length (min = 4, max = 20, pesan = "Harus ada di [4,20]", grup = {groupb.class}) / ** Username* / Private String username; @Notblank @range (min = 0, maks = 100, pesan = "Usia harus di [0,100]", grup = {default.class}) / ** Usia* / usia integer pribadi; @Range (min = 0, maks = 2, pesan = "Jenis kelamin harus di [0,2]", grup = {groupb.class}) /** Jenis Kelamin 0: Tidak Diketahui; 1: pria; 2: wanita*/ seks integer pribadi;}Seperti yang ditunjukkan secara langsung di atas, ketiga kelompok masing -masing divalidasi sebagai berikut:
A. Pengelompokan
Hanya pengelompokan tag GroupA dan GroupB yang diverifikasi:
@RequestMapping ("/Demo5") public void demo5 () {person p = orang baru (); / ** Verifikasi groupa tidak lulus*/ p.setuserid (-12); /** Groupa Verifikasi Pass*///p.setuserid(12); p.setusername ("a"); p.setage (110); p.setsex (5); Set <ConceptViolation <Fon>> Validate = Validator.Validate (p, groupa.class, groupb.class); for (ConstraintViolation <fone> item: validate) {System.out.println (item); }}atau
@RequestMapping ("/Demo6") public void demo6 (@valided ({groupa.class, groupb.class}) orang p, hasil pengikat) {if (result.haserrors ()) {daftar <bjjecterror> allerrors = result.getallerrors (); untuk (kesalahan objecterror: allerrors) {system.out.println (error); }}}Jika Groupa, GroupB, dan Default tidak divalidasi:
Informasi verifikasi adalah sebagai berikut:
ConstiintViolationImpl {InterpolatedMessage = 'harus ada di [4,20]', propertipath = nama pengguna, rootbeAnclass = class validator.demo.project.model.person, messageTemplats = 'harus dalam [4,20]'} constrainviolationImpl {interpolatedm = 0.20] '} constrainviolationImpl {interpolatedm = 0 rootbeAnclass = class validator.demo.project.model.person, messageTemplate = 'harus lebih besar dari 0'} kendalaViolationImpl {interpolatedMessage = 'gender harus ada di [0,2], properti = sex, rootbeanclass = class validator.demo.proect. [0,2] '}Jika verifikasi groupa dilewati, groupb, dan verifikasi default tidak dilewati:
Informasi verifikasi adalah sebagai berikut:
ConstiintViolationImpl {InterpolatedMessage = 'harus ada di [4,20]', propertipath = nama pengguna, rootbeAnclass = class validator.demo.project.model.person, messageTemplats = 'harus di [4.20]'} constrainviolationImpl {interpolatedMess = non -non -non -nexaPeshess = 0.10, 0. 0.SEXIDE, E. rootbeAnclass = class validator.demo.project.model.person, messageTemplate = 'gender harus di [0,2]'}B. Urutan Grup
Selain menentukan apakah akan memverifikasi berdasarkan grup, Anda juga dapat menentukan urutan verifikasi grup. Jika verifikasi grup sebelumnya gagal, verifikasi grup berikutnya tidak akan dilakukan:
Urutan grup yang ditentukan (groupa》 grupb》 default):
@Groupequence ({groupa.class, groupb.class, default.class}) Public Interface Grouporder {}Demo Tes:
@RequestMapping ("/demo7") public void demo7 () {person p = orang baru (); /** Verifikasi groupa tidak lulus*///p.setuserid(-12); / ** Groupa Verifikasi Pass*/ p.setUserId (12); p.setusername ("a"); p.setage (110); p.setsex (5); Set <ConceptViolation <Fon>> Validate = Validator.Validate (P, GroupOrder.class); for (ConstraintViolation <fone> item: validate) {System.out.println (item); }}atau
@RequestMapping ("/Demo8") public void demo8 (@valided ({{grouporder.class}) orang P, hasil BINDINGRESULT) {if (hasil. untuk (kesalahan objecterror: allerrors) {system.out.println (error); }}}Jika Groupa, GroupB, dan Default tidak divalidasi:
Informasi verifikasi adalah sebagai berikut:
ConseptViolationImpl {InterpolatedMessage = 'harus lebih besar dari 0', propertypath = userid, rootbeAnclass = class validator.demo.project.model.person, messageTemplate = 'harus lebih besar dari 0'}Jika verifikasi groupa dilewati, groupb, dan verifikasi default tidak dilewati:
Informasi verifikasi adalah sebagai berikut:
ConstiintViolationImpl {InterpolatedMessage = 'harus ada di [4,20]', propertipath = nama pengguna, rootbeAnclass = class validator.demo.project.model.person, messageTemplats = 'harus di [4.20]'} constrainviolationImpl {interpolatedMess = non -non -non -nexaPeshess = 0.10, 0. 0.SEXIDE, E. rootbeAnclass = class validator.demo.project.model.person, messageTemplate = 'gender harus di [0,2]'}Kesimpulan: Saat memverifikasi urutan pengelompokan, verifikasi dalam urutan pengelompokan yang ditentukan. Jika verifikasi sebelumnya gagal, pengelompokan selanjutnya tidak dapat diverifikasi.
5. Verifier khusus
Secara umum, verifikasi khusus dapat menyelesaikan banyak masalah. Tetapi ada juga saat -saat ketika situasinya tidak dapat dipenuhi. Pada saat ini, kami dapat mengimplementasikan antarmuka validator dan menyesuaikan validator yang kami butuhkan.
Seperti yang ditunjukkan di bawah ini, validator kasus khusus diimplementasikan:
public enum casemode {Upper, lower;}@target ({{elementType.method, elementType.field, elementType.annotation_type})@retention (retentionPolicy.runtime) @constraint (validedby = checkCasevalidator.class) @documentedpublic @interface {string) @document@interface {centang) @document @Interface {centang) @document @Interface {centang) @DocumentBlic Kelas <?> [] Grup () default {}; Kelas <? Extends payload> [] payload () default {}; Value casemode ();} kelas publik checkCasevalidator mengimplementasikan Concternvalidator <checkcase, string> {private casemode casemode; public void initialize (checkcase checkcase) {this.casemode = ceckcase.value (); } public boolean isValid (String S, ConseptValidatorContext ConceptValidatorContext) {if (s == null) {return true; } if (casemode == casemode.upper) {return s.equals (s.touppercase ()); } else {return s.equals (s.tolowercase ()); }}}Model untuk memverifikasi:
Demo kelas publik {@checkcase (value = casemode.lower, message = "nama pengguna harus menjadi huruf kecil") nama pengguna string pribadi; string publik getUserName () {return username; } public void setusername (string username) {this.username = username; }}Konfigurasi Validator:
@Bean public validator validator () {validatorFactory validatorFactory = validation.byprovider (hibernatevalidator.class) .configure () .addproperty ("hibernate.validator.fail_fast", "true") .buildvalidatorFactory (); Validator validator = validatorFactory.getValidator (); validator pengembalian; }Tes Verifikasi:
@RequestMapping ("/demo4") public void demo4 () {demo demo = demo baru (); demo.setusername ("nama pengguna"); Set <ConceptViolation <demo>> Validate = Validator.Validate (Demo); for (ConstraintViolation <demo> dem: validate) {System.out.println (dem.getMessage ()); }}Hasil output:
Nama pengguna harus menjadi huruf kecil
6. Anotasi Umum
Kendala bawaan dalam validasi kacang @null Elemen yang dianotasi harus nol @notnull, elemen yang dianotasi tidak boleh nol @asserttrue, elemen beranotasi harus benar @AssertFalse, elemen yang dianotasi harus lebih dari nilai minimum yang harus dikepung. Sama dengan nilai maksimum yang ditentukan @decimalmin (nilai) Elemen yang dianotasi harus menjadi angka, nilainya harus lebih besar dari atau sama dengan nilai minimum yang ditentukan @Decimalmax (nilai) elemen yang dianotasi harus berupa angka, nilainya harus kurang dari atau sama dengan nilai maksimum yang ditentukan @SIZE (MAX =, Min = Min = Minat dari yang dianamkan di dalamnya ada di dalamnya. Elemen beranotasi harus menjadi angka dan nilainya harus berada dalam kisaran @past yang dapat diterima, elemen beranotasi harus merupakan tanggal masa lalu @future elemen beranotasi harus menjadi tanggal @pattern di masa mendatang (regex =, flag =) elemen beranotasi harus memenuhi ajaran rutin yang ditentukan hibernate validator yang dilampirkan @notblank (pesan =) string verifikasi yang ditentukan dan tora hibernate @non -noT @notblank (pesan =) tidak ada verifikasi yang ditentukan. @Length (min =, max =) String yang dijelaskan harus berada dalam kisaran yang ditentukan @notempty string yang dianotasi harus tidak kosong @range (min =, max =, pesan =) elemen beranotasi harus berada dalam kisaran yang sesuai // lebih besar dari 0,01, tidak mengandung 0,01 @notnull @decimalmin (nilai = "0,01, termasuk = = noTnull @decimalmin (nilai =" 0,01, termasuk = = 0,01 ", termasuk 0,01", tidak ada. 0.01@notnull@decimalmin (value = "0.01", termasuk = true) private BigDecimal Greatorequalthan; @Length (min = 1, max = 20, pesan = "Pesan tidak dapat kosong") // tidak dapat menggunakan panjang //@range (min = 1, maks = 20, pesan = "pesan tidak dapat kosong") pesan string privat;
7. Bahan referensi
Referensi:
http://docs.jboss.org/hibernate/validator/4.2/reference/zh-cn/html_single/#validator-gettingStarted