當我們在任何網絡應用程序中接受用戶輸入時,有必要對其進行驗證。我們可以使用JavaScript在客戶端對用戶輸入進行驗證,但也有必要在服務器端對其進行驗證,以確保在用戶禁用JavaScript的情況下處理有效數據。
Spring 驗證
Spring MVC 框架 預設支援 JSR-303 規範,我們只需在 Spring MVC 應用程式中添加 JSR-303 及其實作相依性。Spring 也提供了 @Validator
註釋和 BindingResult
類別,透過這些我們可以在控制器請求處理方法中獲取 Validator 實作所引發的錯誤。我們可以通過兩種方式創建自定義驗證器實作 – 第一種方式是創建符合 JSR-303 規範的註釋並實作其 Validator 類別。第二種方法是實作 org.springframework.validation.Validator
介面並將其設置為控制器類別中的驗證器,使用 @InitBinder
註釋。讓我們在 Spring Tool Suite 中創建一個簡單的 Spring MVC 項目,我們將使用其實作相依性 hibernate-validator 來使用 JSR-303 規範。我們將使用基於註釋的表單驗證並根據 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>
部署描述符
當您從 STS 創建一個 Spring MVC 專案時,它會創建兩個上下文配置文件。我稍微整理了一下,只留了一個 spring bean 配置文件。我的最終 web.xml 文件如下。
<?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 Bean 配置文件
通常我們最後才查看 spring 的配置,但這次在 spring bean 配置文件中我們沒有太多的配置。我們最終的 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
bean 和用於從資源束讀取本地化數據的 messageSource
bean。其餘部分是為了支持註釋、視圖解析器以及提供控制器類和其他組件的掃描包。
模型類別
在這個專案中,我們有兩個模型類別 – 第一個我們將使用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;
}
}
Employee是一個標準的Java Bean,我們將使用我們自己的驗證器實作來驗證包含Employee Bean的表單。
自定義驗證器實現
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;
//如果輸入與任何規則都不匹配,則返回false
else return false;
}
}
我們的JSR-303規範驗證器實現應該實現javax.validation.ConstraintValidator
接口。如果我們使用某些資源,例如DataSource,我們可以在initialize()
方法中初始化它們。驗證方法是isValid
,如果數據有效則返回true,否則應該返回false。如果您對正則表達式不熟悉,可以在Java正則表達式教程中了解更多。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");
}
}
EmployeeFormValidator是特定于Spring Framework的验证器实现。supports()
方法由Spring Framework实现,用于了解可以使用此验证的对象。我们实现validate()
方法,如果任何字段验证失败,就添加错误。Spring提供org.springframework.validation.ValidationUtils
实用程序类用于基本验证,例如空或为空。一旦此方法返回,Spring框架将Errors对象绑定到我们在控制器处理方法中使用的BindingResult对象。注意ValidationUtils.rejectIfEmptyOrWhitespace()
的最后一个参数是消息资源的键名。通过这种方式,我们可以为用户提供本地化的错误消息。有关Spring中i18n的更多信息,请阅读Spring i18n Example。
Controller Classes
我们有两个控制器类,一个用于基于注释的表单验证,另一个用于我们的自定义验证器。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參數,Spring會負責將其填充為錯誤消息。處理程序方法的邏輯非常簡單,如果有任何錯誤,我們會用相同的頁面作出回應,否則我們會將用戶重定向到成功頁面。另一個重要的注意點是,我們正在將“customer”屬性添加到模型中,這是必要的,以讓Spring框架知道在表單頁面中使用哪個模型對象。如果我們不這樣做,對象綁定到表單數據將不會發生,我們的表單驗證將無法工作。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";
}
}
要使用自定義驗證器,首先我們需要將其注入控制器類中。我們使用spring bean自動連接來實現這一點,使用@Autowired
和@Qualifier
註釋。接下來,我們需要有一個方法,該方法將接受WebDataBinder作為參數,並設置我們要使用的自定義驗證器。該方法應該使用@InitBinder
註釋進行註釋。使用@ModelAttribute
是將我們的bean對象添加到模型的另一種方式。其餘代碼與客戶端控制器實現相似。
表单验证错误消息资源包
现在是时候查看我们的资源包,其中包含用于验证错误的不同类型的消息。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
# 当从表单数据转换为 Bean 失败时,使用 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} 为字段名,其他字段按字母顺序排列,先是 max,然后是 min
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 表单标签获取错误并设置表单 Bean 和变量名称。我们的 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
屬性用於定義要用於數據綁定的對象屬性。其餘代碼是帶有一些CSS用於錯誤消息樣式的標準HTML。我們的 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