عند قبول إدخالات المستخدم في أي تطبيق ويب، يصبح من الضروري التحقق من صحتها. يمكننا التحقق من إدخال المستخدم على الجانب العميل باستخدام JavaScript ولكن من الضروري أيضًا التحقق منها على الجانب الخادم للتأكد من معالجة بيانات صحيحة في حالة تعطيل المستخدم لـ JavaScript.
التحقق في الربيع
الإطار الربيعي لـ MVC يدعم مواصفات JSR-303 بشكل افتراضي، وكل ما نحتاج إليه هو إضافة JSR-303 وتبعيات تنفيذه في تطبيق Spring MVC. يوفر الربيع أيضًا تعليق @Validator
وفئة BindingResult
التي يمكننا من خلالها الحصول على الأخطاء التي تم إثارتها بواسطة تنفيذ الفاحص في طريقة معالج طلب المتحكم. يمكننا إنشاء تنفيذات فاحص مخصصة بطريقتين – الأولى هي إنشاء تعليق يتماشى مع مواصفات JSR-303 وتنفيذ فئتها الفاحصة. النهج الثاني هو تنفيذ واجهة org.springframework.validation.Validator
وتعيينها كفاحص في فئة التحكم باستخدام تعليق @InitBinder
. دعونا نقوم بإنشاء مشروع بسيط لـ Spring MVC في بيئة Spring Tool Suite حيث سنستخدم مواصفات JSR-303 مع فرع التنفيذ الخاص به hibernate-validator. سنستخدم التحقق من النماذج بناءً على التعليقات ونقوم بإنشاء فاحص مخصص الخاص بنا بناءً على معايير JSR-303. سنقوم أيضًا بإنشاء فئة فاحص مخصصة عبر تنفيذ Validator
واستخدامها في إحدى طرق معالج المتحكم. يبدو مشروعنا النهائي كما في الصورة أدناه. دعونا نلقي نظرة على كل من العناصر واحدة تلو الأخرى.
المحقق في تنسيق النموذج Spring MVC
يبدو ملف pom.xml النهائي لدينا كما يلي. بالإضافة إلى فنادق Spring MVC القياسية، لدينا تبعيات لـ validation-api و hibernate-validator في المشروع.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev</groupId>
<artifactId>spring</artifactId>
<name>SpringFormValidation</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.7</java-version>
<org.springframework-version>4.0.2.RELEASE</org.springframework-version>
<org.aspectj-version>1.7.4</org.aspectj-version>
<org.slf4j-version>1.7.5</org.slf4j-version>
</properties>
<dependencies>
<!-- Form Validation using Annotations -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
ملف الوصف للنشر
عند إنشاء مشروع Spring MVC من STS، ينشئ ملفي تكوين السياق. قمت بتنظيفه قليلاً واحتفظت بملف تكوين بين Spring واحد فقط. يبدو ملف الويب النهائي الخاص بي كما يلي.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
ملف تكوين الفاصوليا Spring
عادةً ما ننظر إلى التضاريس الربيعية في النهاية، ولكن هذه المرة ليس لدينا الكثير من التكوينات في ملف تكوين الفاصوليا Spring. يبدو ملفنا النهائي spring.xml كما يلي.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean id="employeeValidator" class="com.journaldev.spring.form.validator.EmployeeFormValidator" />
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:message" />
<beans:property name="defaultEncoding" value="UTF-8" />
</beans:bean>
<context:component-scan base-package="com.journaldev.spring" />
</beans:beans>
النقطة الوحيدة المهمة للملاحظة هي جزء employeeValidator
الذي سنحقنه في أحد المتحكمين وجزء messageSource
لقراءة البيانات الموضوعية من مجموعات الموارد. بقية الجزء هو لدعم التعليقات، وحلول عرض البيانات، وتوفير الحزمة للمسح لفئات المتحكم وغيرها من المكونات.
فئات النموذج
لدينا فئتي نموذج في هذا المشروع – الأولى حيث سنستخدم تعليق JSR-303 ومحققنا المخصص القائم على التعليق والثانية حيث سنستخدم محققنا فقط. كود Customer.java:
package com.journaldev.spring.form.model;
import java.util.Date;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
import com.journaldev.spring.form.validator.Phone;
public class Customer {
@Size(min=2, max=30)
private String name;
@NotEmpty @Email
private String email;
@NotNull @Min(18) @Max(100)
private Integer age;
@NotNull
private Gender gender;
@DateTimeFormat(pattern="MM/dd/yyyy")
@NotNull @Past
private Date birthday;
@Phone
private String phone;
public enum Gender {
MALE, FEMALE
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
لاحظ أننا نستخدم @Email، @NotEmpty و @DateTimeFormat الذين هم إضافيون إلى JSR-303 والمقدمين من تنفيذ محقق Hibernate. بعض تعليقات JSR-303 التي نستخدمها هي @Size، @NotNull، إلخ. @Phone التي تم استخدامها هي تنفيذنا المخصص القائم على مواصفات JSR-303، سنتناول ذلك في القسم التالي. كود Employee.java:
package com.journaldev.spring.form.model;
public class Employee {
private int id;
private String name;
private String role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
الموظف هو فولدر جافا قياسي وسنستخدم تنفيذنا المخصص للتحقق من النموذج مع فولدر الموظف.
تنفيذات المحقق المخصصة
كود Phone.java:
package com.journaldev.spring.form.validator;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import javax.validation.Constraint;
import javax.validation.Payload;
@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Phone {
String message() default "{Phone}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
معظم الجزء هو رمز قالب لتأكيد مع مواصفات JSR-303. الجزء الأكثر أهمية هو التعليق @Constraint حيث نقدم الفئة التي سيتم استخدامها للتحقق من الصحة، أي PhoneValidator
. كود PhoneValidator.java:
package com.journaldev.spring.form.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PhoneValidator implements ConstraintValidator {
@Override
public void initialize(Phone paramA) {
}
@Override
public boolean isValid(String phoneNo, ConstraintValidatorContext ctx) {
if(phoneNo == null){
return false;
}
// قم بالتحقق من أرقام الهاتف بتنسيق "1234567890"
if (phoneNo.matches("\\d{10}")) return true;
// التحقق من رقم الهاتف بوجود - أو . أو مسافات
else if(phoneNo.matches("\\d{3}[-\\.\\s]\\d{3}[-\\.\\s]\\d{4}")) return true;
// التحقق من رقم الهاتف بوجود تمديد بين 3 و 5 أحرف
else if(phoneNo.matches("\\d{3}-\\d{3}-\\d{4}\\s(x|(ext))\\d{3,5}")) return true;
// التحقق من رقم الهاتف حيث يكون رمز المنطقة بين قوسين ()
else if(phoneNo.matches("\\(\\d{3}\\)-\\d{3}-\\d{4}")) return true;
// إرجاع قيمة خاطئة إذا لم يتطابق أي شيء مع المدخلات
else return false;
}
}
يجب أن يقوم محقق JSR-303 لدينا بتنفيذ واجهة javax.validation.ConstraintValidator
. إذا كنا نستخدم بعض الموارد مثل مصدر البيانات، يمكننا تهيئتها في الطريقة initialize()
. الطريقة التي يتم فيها التحقق هي isValid
وتعيد قيمة صحيحة إذا كانت البيانات صحيحة، وإلا يجب أن تعيد قيمة خاطئة. إذا كنت جديدًا على التعابير العادية، يمكنك قراءة المزيد حولها في Java Regular Expressions Tutorial . كود فئة EmployeeFormValidator.java:
package com.journaldev.spring.form.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.journaldev.spring.form.model.Employee;
public class EmployeeFormValidator implements Validator {
// الكائنات التي يمكن التحقق من صحتها باستخدام هذا المحقق
@Override
public boolean supports(Class > paramClass) {
return Employee.class.equals(paramClass);
}
@Override
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "id", "id.required");
Employee emp = (Employee) obj;
if(emp.getId() <=0){
errors.rejectValue("id", "negativeValue", new Object[]{"'id'"}, "id can't be negative");
}
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "name.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "role", "role.required");
}
}
تقوم محررة معلومات الموظف بتنفيذ البرنامج الذي يعتمد على إطار Spring. تنفيذ الطريقة supports()
من قبل إطار Spring لمعرفة الكائنات التي يمكن استخدام هذا التحقق عليها. نحن ننفذ الطريقة validate()
ونضيف الأخطاء إذا فشل التحقق من أي حقل. يوفر Spring فئة الأدوات org.springframework.validation.ValidationUtils
للتحقق الأساسي مثل القيمة الفارغة أو الفارغة. بمجرد أن تعيد هذه الطريقة، يقوم إطار Spring بربط كائن الأخطاء بكائن BindingResult الذي نستخدمه في طريقة معالج الوحدة التحكم الخاصة بنا. لاحظ أن الوسيطة الأخيرة لطريقة ValidationUtils.rejectIfEmptyOrWhitespace()
تأخذ اسم المفتاح لموارد الرسائل. بهذه الطريقة يمكننا توفير رسائل أخطاء مترجمة للمستخدم. لمزيد من المعلومات حول i18n في Spring، اقرأ مثال i18n في Spring.
فئات المتحكم
لدينا فئتي متحكم، واحدة للتحقق من النموذج بناءً على التعليقات وأخرى لمحققنا المخصص. كود فئة CustomerController.java:
package com.journaldev.spring.form.controllers;
import java.util.HashMap;
import java.util.Map;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.form.model.Customer;
@Controller
public class CustomerController {
private static final Logger logger = LoggerFactory
.getLogger(CustomerController.class);
private Map<String, Customer> customers = null;
public CustomerController(){
customers = new HashMap<String, Customer>();
}
@RequestMapping(value = "/cust/save", method = RequestMethod.GET)
public String saveCustomerPage(Model model) {
logger.info("Returning custSave.jsp page");
model.addAttribute("customer", new Customer());
return "custSave";
}
@RequestMapping(value = "/cust/save.do", method = RequestMethod.POST)
public String saveCustomerAction(
@Valid Customer customer,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
logger.info("Returning custSave.jsp page");
return "custSave";
}
logger.info("Returning custSaveSuccess.jsp page");
model.addAttribute("customer", customer);
customers.put(customer.getEmail(), customer);
return "custSaveSuccess";
}
}
عند استخدام التحقق من صحة النموذج المستند إلى التعليقات، نحتاج فقط إلى إجراء تغييرات بسيطة في تنفيذ طريقة معالج الوحدة التحكم الخاصة بنا لجعلها تعمل. أولاً، نحتاج إلى توسيم كائن النموذج الذي نريد التحقق من صحته باستخدام الكود `@Valid
`. ثم نحتاج إلى وجود وسيط BindingResult في الطريقة، حيث يهتم الربيع بملءه برسائل الخطأ. منطق طريقة المعالج بسيط للغاية، إذا كانت هناك أخطاء، فإننا نستجيب بنفس الصفحة، وإلا فإننا نعيد توجيه المستخدم إلى صفحة النجاح. نقطة مهمة أخرى يجب ملاحظتها هي أننا نضيف سمة “customer” إلى النموذج، وهذا ضروري لإعلام إطار الربيع أي كائن نموذجي يجب استخدامه في صفحة النموذج. إذا لم نفعل ذلك، فإن ربط الكائن ببيانات النموذج لن يحدث، ولن يعمل التحقق من صحة النموذج الخاص بنا. كود فئة EmployeeController.java:
package com.journaldev.spring.form.controllers;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.form.model.Employee;
@Controller
public class EmployeeController {
private static final Logger logger = LoggerFactory
.getLogger(EmployeeController.class);
private Map emps = null;
@Autowired
@Qualifier("employeeValidator")
private Validator validator;
@InitBinder
private void initBinder(WebDataBinder binder) {
binder.setValidator(validator);
}
public EmployeeController() {
emps = new HashMap();
}
@ModelAttribute("employee")
public Employee createEmployeeModel() {
// يجب أن يكون قيمة ModelAttribute هي نفسها المستخدمة في empSave.jsp
return new Employee();
}
@RequestMapping(value = "/emp/save", method = RequestMethod.GET)
public String saveEmployeePage(Model model) {
logger.info("Returning empSave.jsp page");
return "empSave";
}
@RequestMapping(value = "/emp/save.do", method = RequestMethod.POST)
public String saveEmployeeAction(
@ModelAttribute("employee") @Validated Employee employee,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
logger.info("Returning empSave.jsp page");
return "empSave";
}
logger.info("Returning empSaveSuccess.jsp page");
model.addAttribute("emp", employee);
emps.put(employee.getId(), employee);
return "empSaveSuccess";
}
}
لاستخدام المحقق المخصص، نحتاج أولاً إلى حقنه في فئة المتحكم. نستخدم توصيل الحبل التلقائي للحبوب الربيعية لتحقيق ذلك باستخدام التوسيمات `@Autowired
` و `@Qualifier
`. بعد ذلك نحتاج إلى وجود طريقة ستأخذ WebDataBinder كوسيط ونقوم بتعيين المحقق المخصص ليتم استخدامه. يجب أن تكون هذه الطريقة موسومة بالتوسيم `@InitBinder
`. استخدام `@ModelAttribute
` هو طريقة أخرى لإضافة كائن الحبوب الخاص بنا إلى النموذج. باقي الكود مشابه لتنفيذ متحكم العميل.
مجموعة موارد رسائل خطأ التحقق من النماذج
حان الوقت للنظر في مجموعة الموارد الخاصة بنا حيث لدينا أنواع مختلفة من الرسائل التي يمكن استخدامها لأخطاء التحقق. ملف message_en.properties:
# رسائل الخطأ المحددة من قبل التطبيق
id.required=Employee ID is required
name.required=Employee Name is required
role.required=Employee Role is required
negativeValue={0} can't be negative or zero
# رسائل خطأ إطار Spring لاستخدامها عند فشل التحويل من بيانات النموذج إلى كائن
typeMismatch.int={0} Value must be an integer
typeMismatch.java.lang.Integer={0} must be an integer
typeMismatch={0} is of invalid format
# رسائل التطبيق للتعليقات، {ValidationClass}.{modelObjectName}.{field}
# {0} هو اسم الحقل، والحقول الأخرى مرتبة أبجدياً، الحد الأقصى ثم الحد الأدنى
Size.customer.name=Customer {0} should be between {2} and {1} characters long
NotEmpty.customer.email=Email is a required field
NotNull.customer.age=Customer {0} should be in years
# رسائل فئة التعليقات العامة
Email=Email address is not valid
NotNull=This is a required field
NotEmpty=This is a required field
Past=Date should be Past
# تعليق التحقق المخصص
Phone=Invalid format, valid formats are 1234567890, 123-456-7890 x1234
I have provided message key details in the comment itself, so I will skip them here. The only important point to note here is the way messages will be looked up, first key name {ValidationClass}.{modelObjectName}.{field} is looked up and if that is not found then {ValidationClass}.{modelObjectName} is looked up. If that is missing, then finally {ValidationClass} key is looked up. If nothing is found then the default message provided will be returned. Read more about resource messages at Spring Localization Example.
صفحات العرض مع النماذج والأخطاء
نظرًا لأننا نستخدم تنفيذ التحقق من إطار Spring، يتعين علينا استخدام علامات نموذج Spring للحصول على الأخطاء وتعيين أسماء النموذج والمتغيرات. يتم توفير كود ملف custSave.jsp لدينا أدناه.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="https://www.springframework.org/tags/form"
prefix="springForm"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Save Page</title>
<style>
.error {
color: #ff0000;
font-style: italic;
font-weight: bold;
}
</style>
</head>
<body>
<springForm:form method="POST" commandName="customer"
action="save.do">
<table>
<tr>
<td>Name:</td>
<td><springForm:input path="name" /></td>
<td><springForm:errors path="name" cssClass="error" /></td>
</tr>
<tr>
<td>Email:</td>
<td><springForm:input path="email" /></td>
<td><springForm:errors path="email" cssClass="error" /></td>
</tr>
<tr>
<td>Age:</td>
<td><springForm:input path="age" /></td>
<td><springForm:errors path="age" cssClass="error" /></td>
</tr>
<tr>
<td>Gender:</td>
<td><springForm:select path="gender">
<springForm:option value="" label="Select Gender" />
<springForm:option value="MALE" label="Male" />
<springForm:option value="FEMALE" label="Female" />
</springForm:select></td>
<td><springForm:errors path="gender" cssClass="error" /></td>
</tr>
<tr>
<td>Birthday:</td>
<td><springForm:input path="birthday" placeholder="MM/dd/yyyy"/></td>
<td><springForm:errors path="birthday" cssClass="error" /></td>
</tr>
<tr>
<td>Phone:</td>
<td><springForm:input path="phone" /></td>
<td><springForm:errors path="phone" cssClass="error" /></td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Save Customer"></td>
</tr>
</table>
</springForm:form>
</body>
</html>
commandName="customer"
يُستخدم لتعيين اسم سمة النموذج التي يتم تعريض كائن النموذج تحتها. القيمة الافتراضية هي “command” ، لذا يجب علينا تعيينها بالقيمة الافتراضية لسمة النموذج التي نستخدمها في فصول تحكمنا. springForm:errors
يُستخدم لتقديم الأخطاء ، إذا كانت هناك، عند تقديم الصفحة. يُستخدم السمة path
لتحديد خاصية الكائن المراد استخدامها لربط البيانات. باقي الشيفرة هو HTML قياسي مع بعض CSS لتنسيق رسائل الأخطاء. ملف custSaveSuccess.jsp الخاص بنا معطى أدناه.
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="https://java.sun.com/jsp/jstl/fmt" %>
<%@ page session="false" %>
<html>
<head>
<title>Customer Saved Successfully</title>
</head>
<body>
<h3>
Customer Saved Successfully.
</h3>
<strong>Customer Name:${customer.name}</strong><br>
<strong>Customer Email:${customer.email}</strong><br>
<strong>Customer Age:${customer.age}</strong><br>
<strong>Customer Gender:${customer.gender}</strong><br>
<strong>Customer Birthday:<fmt:formatDate value="${customer.birthday}" type="date" /></strong><br>
</body>
</html>
صفحة JSP بسيطة تظهر قيم العميل إذا لم تكن هناك أخطاء في التحقق من الصحة ويتم إرجاع هذه الصفحة كاستجابة. اسمها empSave.jsp.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="https://www.springframework.org/tags/form"
prefix="springForm"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Employee Save Page</title>
<style>
.error {
color: #ff0000;
font-style: italic;
font-weight: bold;
}
</style>
</head>
<body>
<springForm:form method="POST" commandName="employee"
action="save.do">
<table>
<tr>
<td>Employee ID:</td>
<td><springForm:input path="id" /></td>
<td><springForm:errors path="id" cssClass="error" /></td>
</tr>
<tr>
<td>Employee Name:</td>
<td><springForm:input path="name" /></td>
<td><springForm:errors path="name" cssClass="error" /></td>
</tr>
<tr>
<td>Employee Role:</td>
<td><springForm:select path="role">
<springForm:option value="" label="Select Role" />
<springForm:option value="ceo" label="CEO" />
<springForm:option value="developer" label="Developer" />
<springForm:option value="manager" label="Manager" />
</springForm:select></td>
<td><springForm:errors path="role" cssClass="error" /></td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Save"></td>
</tr>
</table>
</springForm:form>
</body>
</html>
ملف empSaveSuccess.jsp:
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Employee Saved Successfully</title>
</head>
<body>
<h3>
Employee Saved Successfully.
</h3>
<strong>Employee ID:${emp.id}</strong><br>
<strong>Employee Name:${emp.name}</strong><br>
<strong>Employee Role:${emp.role}</strong><br>
</body>
</html>
قم بتجربة تطبيق التحقق من صحة نموذج Spring MVC
تطبيقنا جاهز للنشر وتشغيل بعض الاختبارات، قم بنشره في حاوي Servlet المفضلة لديك. أنا استخدم Apache Tomcat 7 وأدناه تظهر بعض الصور لبعض الصفحات مع رسائل أخطاء التحقق. استنادًا إلى بيانات الإدخال الخاصة بك، قد تحصل على رسائل أخطاء مختلفة أيضًا.
هذا كل شيء بخصوص التحقق من صحة نموذج Spring MVC بطرق مختلفة واستخدام حزم الموارد لرسائل الأخطاء المترجمة. يمكنك تنزيل المشروع العيني من الرابط أدناه والتلاعب به للمزيد من التعلم.
Source:
https://www.digitalocean.com/community/tutorials/spring-validation-example-mvc-validator