1. التحقق من المعلمة
في التطوير ، غالبًا ما تحتاج إلى كتابة بعض التعليمات البرمجية للتحقق من الحقل ، مثل الحقول غير الفارغة ، وحدود طول الحقل ، والتحقق من تنسيق صندوق البريد ، وما إلى ذلك.
يوفر مصادقة Hibernate (المستند الرسمي) طريقة تنفيذ التحقق كاملة ومريحة نسبيًا.
تحتوي حزمة Web-Web على حزمة الفراشات على السبات ، وليس هناك حاجة للإشارة إلى تبعية المدقق.
2.
دعونا أولاً نلقي نظرة على عرض تجريبي بسيط ، مضيفًا توضيح المدقق:
استيراد org.hibernate.validator.constraints.notblank ؛ استيراد javax.validation.constraints.assertfalse ؛ import javax.validation.constraints.pattern ؛
@getter@setter@noargsconstructorpublic class demomodel {notblank (message = "اسم المستخدم لا يمكن أن يكون فارغًا") اسم المستخدم الخاص ؛ notblank (message = "Age لا يمكن أن يكون فارغًا") pattern (regexp = "^[0-9] {1،2} $" ، message = "Age غير صحيح") العمر الخاص ؛ ASTERTFALSE (message = "يجب أن يكون خطأ") private boolean isFalse ؛ / *** إذا كان فارغًا ، فلن يتم التحقق منه ، وإذا لم يكن فارغًا ، فسيتم فحصه*/ @pattern (regexp = "^[0-9] {4}-[0-9] {2}-[0-9] {2} $" ، message = "تاريخ الميلاد غير صحيح")بعد التحقق من الواجهة ، يعد BindingResult مجموعة من النتائج التي تفشل في تمرير التحقق:
requestmapping ("/demo2") demo2 public void (requestbodyvalid demomodel demo ، bindingresult result) {if (result.haserrors ()) {for (error erbounror error: result.getAllerRors ()) {system.out.println (error.getDefaultMessage () ؛ }}} تم تمرير المعلمات بواسطة طلب النشر :{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}
نتيجة الإخراج:
تاريخ الميلاد غير صحيح ويجب أن يكون خطأ
العمر غير صحيح
التحقق من المعلمة مريحة للغاية. إذا لم يتم تمرير التحقق من التعليقات التوضيحية + على الحقل ، فيمكنه استبدال خط اليد بالكثير من رموز التحقق من التقييد غير الفارغة والميدان. أدناه لدينا فهم أعمق لكيفية لعب التحقق من المعلمة.
3. وضع التحقق من السبات
يجب أن يكون القراء الدقيقون قد اكتشفوا أنه في المثال أعلاه ، يتم إرجاع جميع المجموعات التي تفشل في تمرير التحقق مرة واحدة. عادة ، عندما لا يفي الحقل الأول بمتطلبات التحقق بالترتيب ، يمكن رفض الطلب مباشرة. يحتوي مصادقة السبات على وضعي التحقق التاليان:
1. الوضع العادي (هذا الوضع افتراضي)
الوضع العادي (سيتم فحص جميع السمات ثم يتم إرجاع جميع معلومات فشل التحقق)
2. فشل سريع في العودة إلى الوضع
وضع إرجاع الفشل السريع (العودة طالما كان هناك فشل التحقق)
طريقتان لتكوين وضع التحقق: (ارجع إلى الوثائق الرسمية)
Failfast: وضع إرجاع FAIL FAIL FAIL FALL الوضع العادي
ValidatorFactory ValitatorFactory = Validation.Bervider (HibernateValidator.Class). التحقق من التحقق = ValitatorFactory.getValidator () ؛
و (hibernate.validator.fail_fast: وضع إرجاع FAIL FAST صحيح الوضع العادي الخاطئ)
ValidatorFactory ValitatorFactory = Valide.bervider (hibernatevalidator.class) .Configure () .addproperty ("hibernate.validator.fail_fast" ، "true") .buildvalidatorfactory () ؛ التحقق من التحقق = ValitatorFactory.getValidator () ؛4. نوعان من التحديات من السبات
تكوين مدقق السبات إلى وضع الإرجاع إلى الفشل السريع:
ConfigurationPublic Class ValidatorConfiguration {Bean Public Validator () {ValitatorFactory ValidatorFactory = Validation.byprovider (hibernatevalidator.class) .Configure () .AddProperty ("hibernate.validator.fail_fast" التحقق من التحقق = ValitatorFactory.getValidator () ؛ مدقق إرجاع ؛ }}1. طلب التحقق من المعلمة
كما هو الحال في المثال في العرض التوضيحي ، عند التحقق من معلمات الطلب ، أضف Valid بين Demomodel Demo ، ثم إضافة BindIndResult ؛ بالنسبة لمعلمات متعددة ، يمكنك إضافة متعددة @valid و bindingresult ، مثل:
اختبار الفراغ العام () ( @requestbodyvalid demomodel demo ، bindingresult نتيجة) اختبار الفراغ العام () (requestbodyvalid demomodel demo ، نتيجة bindingresult ، @requestbodyvalid demoModel demo2 ، bindingresult result2)
requestmapping ("/demo2") demo2 public void (requestbodyvalid demomodel demo ، bindingresult result) {if (result.haserrors ()) {for (error erbounror error: result.getAllerRors ()) {system.out.println (error.getDefaultMessage () ؛ }}}2. احصل على التحقق من المعلمة (التحقق من المعلمة requestparam)
باستخدام طريقة فحص الفاصوليا ، لا توجد طريقة للتحقق من محتوى requestParam. بشكل عام ، عند المعالجة ، احصل على طلبات (أو عدد أقل من المعلمات) ، سيتم استخدام الكود التالي:
requestmapping (value = "/demo3" ، method = requestMethod.get) demo3 public void (@requestparam (name = "grade" ، required = true) int ،@requestparam (name = "classroom" ، required = true) int classroom) {system.out.println (date + "،" + classroom) ؛ }باستخدام التعليق التوضيحي ValID لتعليق المعلمات المقابلة لـ requestParam غير صالح. مطلوب التعليق التوضيحي المعدل لجعل التحقق يسري. كما هو موضح أدناه:
أ. في هذا الوقت ، تحتاج إلى استخدام Bean of MethodValidationPostProcessor :
Bean Public MethodValidationPostProcessor MethodValidationPostProcessor () { / ** الافتراضي هو الوضع العادي ، وسيتم إرجاع جميع التحديات دون تمرير جمع المعلومات* / إرجاع طريقة جديدة للمعادن PostProcessor () ؛ } أو يمكنك تعيين المدقق لـ MethodValidationPostProcessor (لأن المدقق لا يستخدم للتحقق في هذا الوقت ، لا يعمل تكوين المدقق)
bean public methodValidationPostProcessor methodValidationPostProcessor () {methodValidationPostProcessor postprocessor = new MethodValidationPostProcessor () ؛ / ** تعيين وضع التحقق من عودة الفشل السريع*/ postprocessor.setValidator (Valitator ()) ؛ إرجاع ما بعد المعالج ؛ } bean public deadator () {ValitatorFactory ValitorFactory = Validation.bervidider (hibernatevalidator.class) .Configure () .AddProperty ("hibernate.validator.fail_fast" ، "true") .buildvalidatorfactory () ؛ التحقق من التحقق = ValitatorFactory.getValidator () ؛ مدقق إرجاع ؛ }ب. أضف التعليقات التوضيحية إلى وحدة التحكم حيث يتم تحديد الأسلوب
requestmapping (" /التحقق من الصحة")@restController@ValudatedPublic Class ClassController { /** إذا كان هناك عدد قليل من الكائنات ، فما عليك سوى كتابة المعلمات إلى طبقة وحدة التحكم ثم تحقق منها في طبقة وحدة التحكم. */ @requestmapping (value = "/ demo3" ، method = requestMethod.get) demo3 void public (min = 1 ، max = 9 ، message = "يمكن أن يكون الصف من 1-9") لا يمكن أن يكون فقط 1 "، message = 99 ، message = 99 ، 99 ") @requestparam (name =" classroom "، مطلوب = صواب) }}ج. العودة إلى موجه معلومات التحقق
يمكنك أن ترى: عندما يفشل التحقق ، يتم إلقاء استثناء من constrientviolationexception ويتم التعامل مع نفس استثناء الصيد:
@controllerAdvice @componentpublic class GlobalExceptionHandler {exceptionHandlerlerResponsebodyResponsestatus (httpstatus.bad_request) مقبض السلسلة العامة (استثناء ValidationException) {if (استثناء مثيل strientviolationException) {constrentviolationexception exs = (convalideViolation) ؛ تعيين <constraintViolation <؟ >> انتهاكات = exs.getConstraintViolations () ؛ لـ (constraintviolation <؟> العنصر: انتهاكات) { / ** طباعة المعلومات التي تفشل في تمرير التحقق* / system.out.println (item.getMessage ()) ؛ }} إرجاع "طلب سيء ،" ؛ }}د. تَحَقّق
عنوان طلب خدمة المتصفح: http: // localhost: 8080/التحقق/demo3؟ الصف = 18 والفصول الدراسية = 888
معلومات الإخراج عندما يتم إرجاع MethodValidationPostProcessor دون تكوين الفشل السريع على النحو التالي:
يمكن أن تكون الدرجات من 1-9 فقط
يمكن أن يكون الحد الأقصى للطبقة 99 فقط
عند تكوين MethodValidationPostProcessor مع إرجاع الفشل السريع ، تكون معلومات الإخراج كما يلي:
يمكن أن تكون الدرجات من 1-9 فقط
عنوان طلب خدمة المتصفح: http: // localhost: 8080/التحقق/demo3؟ الصف = 0 والفصول الدراسية = 0
معلومات الإخراج عندما يتم إرجاع MethodValidationPostProcessor دون تكوين الفشل السريع على النحو التالي:
يمكن أن تكون الدرجات من 1-9 فقط
يمكن أن يكون الحد الأدنى للصف واحد فقط
عند تكوين MethodValidationPostProcessor مع إرجاع الفشل السريع ، تكون معلومات الإخراج كما يلي:
يمكن أن تكون الدرجات من 1-9 فقط
3. التحقق من النموذج
النموذج الذي سيتم التحقق منه:
datapublic class demo2 {length (min = 5 ، max = 17 ، message = "طول الطول هو بين [5،17]") طول السلسلة الخاصة ؛ / ** @الحجم لا يمكن التحقق من عدد صحيح ، مناسب للسلسلة ، التجميع ، الخريطة والصفائف*/ size (min = 1 ، max = 3 ، message = "الحجم بين [1،3]") عمر السلسلة الخاصة ؛ Range (min = 150 ، max = 250 ، message = "المدى بين [150،250]") private int High ؛ size (min = 3 ، max = 5 ، message = "حجم القائمة في [3،5]") قائمة خاصة <string> قائمة ؛}تحقق من النموذج ، يتم تمرير جميع التحقيقات التالية:
@autowired صادقة المدقق الخاص ؛ requestmapping ("/demo3") public void demo3 () {demo2 demo2 = new Demo2 () ؛ demo2.setage ("111") ؛ Demo2.Sethigh (150) ؛ Demo2.SetLength ("ABCDE") ؛ DEMO2.SetList (ArrayList جديد <string> () {{add ("111") ؛ add ("222") ؛ add ("333") ؛}}) ؛ SET <CONSTANTVIOLATION <DEMO2 >> CONSTINGET = VELITATOR.VALIDATER (DEMO2) ؛ لـ (constraintviolation <memo2> النموذج: انتهاكات) {system.out.println (model.getMessage ()) ؛ }}4. التحقق من شلالات الكائن
يحتوي الكائن على كائن آخر كخاصية ، ويضيف Valid إلى الخاصية للتحقق من التحقق داخل الكائن كخاصية: (عند التحقق من مثال Demo2 ، يمكنك التحقق من حقول Demo2)
datapublic class demo2 {size (min = 3 ، max = 5 ، message = "حجم القائمة في [3،5]") قائمة خاصة <string> ؛ notnulldvalid private demo3 demo3 ؛} @datapublic class demo3 {length (min = 5 ، max = 17 ، message = "طول الطول بين [5،17]")التحقق من سلسلة:
/ ** تم تكوين Bean مع عودة الفشل السريع Bean*/ @Autowired صدق صدق خاص ؛ requestmapping ("/demo3") public void demo3 () {demo2 demo2 = new Demo2 () ؛ DEMO2.SetList (ArrayList جديد <string> () {{add ("111") ؛ add ("222") ؛ add ("333") ؛}}) ؛ Demo3 Demo3 = New Demo3 () ؛ demo3.setextfield ("22") ؛ demo2.setDemo3 (Demo3) ؛ SET <CONSTANTVIOLATION <DEMO2 >> CONSTINGET = VELITATOR.VALIDATER (DEMO2) ؛ لـ (constraintviolation <memo2> النموذج: انتهاكات) {system.out.println (model.getMessage ()) ؛ }}يمكن التحقق من حقل Extfield of Demo3.
5. التحقق من المجموعة
الخلاصة: عند التحقق من تسلسل التجميع ، تحقق منه في ترتيب التجميع المحدد. إذا فشل التحقق السابق ، فلا يمكن التحقق من التجميع اللاحق.
هناك سيناريو حيث تتم إضافة معلومات مستخدم جديدة ، ليست هناك حاجة للتحقق من معرف المستخدم (لأنه يتم إنشاء النظام) ؛ عند التعديل ، يحتاج المستخدم إلى التحقق من معرف المستخدم ، ويمكن استخدام وظيفة التحقق من المجموعة للمستخدم إلى التحقق.
اضبط المدقق على وضع التحقق العادي ("hibernate.validator.fail_fast" ، "false") ، واستخدم مجموعة التحقق ، GroupB والنموذج:
Groupa ، GroupB: Public Interface Groupa {} واجهة عامة GroupB {}تحقق من النموذج: الشخص
datapublic class person {notBlankRange (min = 1 ، max = integer.max_value ، message = "يجب أن يكون أكبر من 0" ، المجموعات = {groupa.class}) / ** معرف المستخدم* / userid userid ؛ notblanklength (min = 4 ، max = 20 ، message = "يجب أن يكون في [4،20]" ، المجموعات = {groupb.class}) / ** اسم المستخدم* / سلسلة السلسلة الخاصة ؛ notBlankRange (min = 0 ، max = 100 ، message = "يجب أن يكون العصر في [0،100]" ، المجموعات = {default.class}) / ** العمر* / عصر العدد الخاص ؛ range (min = 0 ، max = 2 ، message = "يجب أن يكون الجنس في [0،2]" ، المجموعات = {groupb.class}) /** الجنس 0: غير معروف ؛ 1: ذكر 2: أنثى*/ الجنس العدد الخاص ؛}كما هو موضح في شخص أعلاه ، يتم التحقق من صحة المجموعات الثلاث على التوالي على النحو التالي:
أ. التجميع
يتم التحقق من مجموعات GroupA و GroupB فقط:
requestmapping ("/demo5") public void demo5 () {person p = new person () ؛ / ** لا يمر التحقق من Groupa*/ p.setUserId (-12) ؛ /** Groupa التحقق تمريرة*///p.setuserid(12) ؛ P.SetUserName ("A") ؛ P.Setage (110) ؛ P.SetSex (5) ؛ SET <CONSTANTVIOLATION <PERISE >> VEVIVER = Validator.validate (P ، GroupA.Class ، GroupB.Class) ؛ لـ (constraintViolation <Phone> العنصر: التحقق) {system.out.println (item) ؛ }}أو
requestmapping ("/demo6") demo6 void public (@validated ({groupa.class ، groupb.class}) person p ، bindingResult result) {if (result.haserrors ()) {list <Objecterror> allerrors = result.getAllerRors () ؛ لـ (ObjectError error: allerrors) {system.out.println (error) ؛ }}}إذا لم يتم التحقق من صحة Groupa و GroupB و Default:
معلومات التحقق هي كما يلي:
constraintViolationImpl {interpolatedMessage = 'يجب أن يكون في [4،20]' ، propertypath = username ، rootbeanclass = class classedator.demo.project.model.person adadator.demo.project.model.person ، messageTemplate = 'يجب أن يكون أكبر من 0'} crodentViolationImpl {interpolatedMessage = 'الجنس يجب أن يكون في [0،2]' ، propertypath = sex ، rootbeanclass = class adadator.demo.project.model.person ،إذا تم تمرير التحقق من GroupA ، فلا يتم تمرير GroupB ، والتحقق الافتراضي:
معلومات التحقق هي كما يلي:
constrentviolationImpl {interpolatedMessage = 'يجب أن يكون في [4،20]' ، propertypath = username ، rootbeanclass = class classedator.demo.project.model.person ROOTBEANCLASS = Class Validator.demo.project.model.person ، messageTemplate = 'يجب أن يكون الجنس في [0،2]'}ب. تسلسل المجموعة
بالإضافة إلى تحديد ما إذا كنت تريد التحقق حسب المجموعة ، يمكنك أيضًا تحديد ترتيب التحقق للمجموعة. إذا فشل التحقق من المجموعة السابقة ، فلن يتم إجراء التحقق من المجموعة التالية:
تسلسل المجموعة المحددة (Groupa》 GroupB》 الافتراضي):
GroupSequence ({groupa.class ، groupb.class ، default.class}) واجهة عامة grouporder {}اختبار التوضيح:
requestMapping ("/demo7") public void demo7 () {person p = new person () ؛ /** لا يمر التحقق من Groupa*///p.setuserid(-12) ؛ / ** Groupa التحقق تمريرة*/ p.setUserid (12) ؛ P.SetUserName ("A") ؛ P.Setage (110) ؛ P.SetSex (5) ؛ SET <CONSTRANTVIOLATION <PERISE >> VEVIDATION = VELARDATOR.Validate (P ، GroupOrder.Class) ؛ لـ (constraintViolation <Phone> العنصر: التحقق) {system.out.println (item) ؛ }}أو
requestmapping ("/demo8") demo8 public void (@validated ({grouporder.class}) person p ، bindingResult result) {if (result.haserrors ()) {list <BomberRor> allerrors = result.getAllerRors () ؛ لـ (ObjectError error: allerrors) {system.out.println (error) ؛ }}}إذا لم يتم التحقق من صحة Groupa و GroupB و Default:
معلومات التحقق هي كما يلي:
constrentviolationImpl {interpolatedMessage = 'يجب أن يكون أكبر من 0' ، propertyPath = userId ، rootbeanclass = class adadator.demo.project.model.person ، messageTemplate = 'يجب أن يكون أكبر من 0'}إذا تم تمرير التحقق من GroupA ، فلا يتم تمرير GroupB ، والتحقق الافتراضي:
معلومات التحقق هي كما يلي:
constrentviolationImpl {interpolatedMessage = 'يجب أن يكون في [4،20]' ، propertypath = username ، rootbeanclass = class classedator.demo.project.model.person ROOTBEANCLASS = Class Validator.demo.project.model.person ، messageTemplate = 'يجب أن يكون الجنس في [0،2]'}الخلاصة: عند التحقق من تسلسل التجميع ، تحقق منه في ترتيب التجميع المحدد. إذا فشل التحقق السابق ، فلا يمكن التحقق من التجميع اللاحق.
5. التحقق المخصص
بشكل عام ، يمكن للتحقق المخصص حل العديد من المشكلات. ولكن هناك أيضًا أوقات لا يمكن فيها الوفاء بالموقف. في هذا الوقت ، يمكننا تنفيذ واجهة المدقق وتخصيص المدقق الذي نحتاجه.
كما هو موضح أدناه ، يتم تنفيذ التحقق من حالة مخصصة:
التعداد العام casemode {apport ، lower ؛}@target ({elementType.method ، elementType.field ، elementType.annotation_type})@entry (attreence.runtime) constraint ( الفئة <؟> [] المجموعات () الافتراضي {} ؛ الفئة <؟ يمتد Payload> [] Payload () افتراضي {} ؛ casemode value () ؛} checkcasevalidator من الفئة العامة تنفذ constrentvalidator <checkcase ، string> {private casemode casemode ؛ تهيئة public void (checkcase checkcase) {this.casemode = checkcase.value () ؛ } iSvalid boolean العامة (سلسلة S ، constraintValIdatorContext crodentValidatorContext) {if (s == null) {return true ؛ } if (casemode == casemode.upper) {return s.equals (s.toupperCase ()) ؛ } آخر {return S.Equals (S.ToLowerCase ()) ؛ }}}نموذج للتحقق:
Demo Class Public {checkcase (value = casemode.lower ، message = "يجب أن يكون اسم المستخدم صغيرًا") اسم مستخدم السلسلة الخاصة ؛ السلسلة العامة getUserName () {return username ؛ } public void setusername (string username) {this.userName = username ؛ }}تكوين المدقق:
@bean public deadator () {validatorFactory ValidatorFactory = Validation.Byprovider (hibernatevalidator.class) .Configure () .addproperty ("hibernate.validator.fail_fast" ، "true") .buildvalidatorfactory () ؛ التحقق من التحقق = ValitatorFactory.getValidator () ؛ مدقق إرجاع ؛ }اختبار التحقق:
requestmapping ("/demo4") public void demo4 () {demo demo = new demo () ؛ Demo.SetUserName ("اسم المستخدم") ؛ SET <CONSTANTVIOLATION <DEMO >> VEVIDATION = VALDATOR.Validate (DEMO) ؛ لـ (constraintViolation <memo> dem: التحقق) {system.out.println (dem.getMessage ()) ؛ }}نتيجة الإخراج:
يجب أن يكون اسم المستخدم صغيرًا
6. التعليقات التوضيحية المشتركة
القيد المدمج في التحقق من صحة الفاصوليا @null يجب أن يكون العنصر المشروح فارغًا notnull يجب ألا يكون العنصر المشروح فارغًا ، يجب أن يكون العنصر المشروح هو العدد ، يجب أن يكون قيمته أكبر من القيمة المحددة (القيمة المحددة). إلى الحد الأقصى المحدد القيمة المحددة decimalmin (القيمة) يجب أن يكون العنصر المشروح رقمًا ، ويجب أن تكون قيمته أكبر من أو تساوي القيمة الدنيا المحددة @decimalmax (القيمة) يجب أن يكون العنصر المشروح هو حجم العنصر المرفق أو تساويه (annot). يجب أن يكون رقمًا ويجب أن تكون قيمته ضمن النطاق المقبول ، يجب أن يكون العنصر المشروح هو تاريخ الماضي future يجب أن يكون العنصر المشروح هو datepattern @regex = ، flag =) length (min = ، max =) يجب أن تكون السلسلة المشروحة ضمن النطاق المحدد @notempty يجب أن تكون السلسلة المشروحة غير فارغة (min = ، max = ، message =) يجب أن يكون العنصر المشروح ضمن النطاق المناسب // أكبر من 0.01 ، لا يحتوي 0.01@notnull@decimalmin (value = "0.01" ، بما في ذلك = صواب) BigDecimal greatorequalthan ؛ unternength (min = 1 ، max = 20 ، message = "message لا يمكن أن تكون فارغة") // لا يمكن استخدام الطول كنطاق //@range (min = 1 ، max = 20 ، message = "message لا يمكن أن تكون فارغة")
7. المواد المرجعية
مراجع:
http://docs.jboss.org/hibernate/validator/4.2/reference/zh-cn/html_single/#validator-gettingstarted