Spring 验证示例 - Spring MVC 表单验证器

当我们在任何 Web 应用程序中接受用户输入时,我们可以使用 JavaScript 验证客户端的用户输入,但也需要在服务器端验证它们,以确保在用户禁用 javascript 时我们正在处理有效的数据。

春季验证

Spring MVC Framework supports JSR-303 specs by default and all we need is to add JSR-303 and it's implementation dependencies in Spring MVC application. Spring also provides @Validator annotation and BindingResult class through which we can get the errors raised by Validator implementation in the controller request handler method. We can create our custom validator implementations in two ways - the first one is to create an annotation that confirms to the JSR-303 specs and implement its Validator class. Second approach is to implement the org.springframework.validation.Validator interface and add set it as validator in the Controller class using @InitBinder annotation. Let's create a simple Spring MVC project in Spring Tool Suite where we will use JSR-303 specs with it's implementation artifact hibernate-validator. We will use annotation based form validation and create our own custom validator based on JSR-303 specs standards. We will also create our own custom validator class by implementing Validator interface and use it in one of the controller handler methods. Our final project looks like below image. Spring Validation Example Let's look at each of the components one by one.

春季MVC形式验证器

除了标准的春季MVC文物,我们在项目中有验证API和冬眠验证器依赖。

  1<?xml version="1.0" encoding="UTF-8"?>
  2<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  3    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
  4    <modelVersion>4.0.0</modelVersion>
  5    <groupId>com.journaldev</groupId>
  6    <artifactId>spring</artifactId>
  7    <name>SpringFormValidation</name>
  8    <packaging>war</packaging>
  9    <version>1.0.0-BUILD-SNAPSHOT</version>
 10    <properties>
 11    	<java-version>1.7</java-version>
 12    	<org.springframework-version>4.0.2.RELEASE</org.springframework-version>
 13    	<org.aspectj-version>1.7.4</org.aspectj-version>
 14    	<org.slf4j-version>1.7.5</org.slf4j-version>
 15    </properties>
 16    <dependencies>
 17    <!-- Form Validation using Annotations -->  
 18    	<dependency>
 19    		<groupId>javax.validation</groupId>
 20    		<artifactId>validation-api</artifactId>
 21    		<version>1.1.0.Final</version>
 22    	</dependency>
 23    	<dependency>
 24    		<groupId>org.hibernate</groupId>
 25    		<artifactId>hibernate-validator</artifactId>
 26    		<version>4.1.0.Final</version>
 27    	</dependency>
 28    	
 29    	<!-- Spring -->
 30    	<dependency>
 31    		<groupId>org.springframework</groupId>
 32    		<artifactId>spring-context</artifactId>
 33    		<version>${org.springframework-version}</version>
 34    		<exclusions>
 35    			<!-- Exclude Commons Logging in favor of SLF4j -->
 36    			<exclusion>
 37    				<groupId>commons-logging</groupId>
 38    				<artifactId>commons-logging</artifactId>
 39    			</exclusion>
 40    		</exclusions>
 41    	</dependency>
 42    	<dependency>
 43    		<groupId>org.springframework</groupId>
 44    		<artifactId>spring-webmvc</artifactId>
 45    		<version>${org.springframework-version}</version>
 46    	</dependency>
 47
 48    	<!-- AspectJ -->
 49    	<dependency>
 50    		<groupId>org.aspectj</groupId>
 51    		<artifactId>aspectjrt</artifactId>
 52    		<version>${org.aspectj-version}</version>
 53    	</dependency>
 54
 55    	<!-- Logging -->
 56    	<dependency>
 57    		<groupId>org.slf4j</groupId>
 58    		<artifactId>slf4j-api</artifactId>
 59    		<version>${org.slf4j-version}</version>
 60    	</dependency>
 61    	<dependency>
 62    		<groupId>org.slf4j</groupId>
 63    		<artifactId>jcl-over-slf4j</artifactId>
 64    		<version>${org.slf4j-version}</version>
 65    		<scope>runtime</scope>
 66    	</dependency>
 67    	<dependency>
 68    		<groupId>org.slf4j</groupId>
 69    		<artifactId>slf4j-log4j12</artifactId>
 70    		<version>${org.slf4j-version}</version>
 71    		<scope>runtime</scope>
 72    	</dependency>
 73    	<dependency>
 74    		<groupId>log4j</groupId>
 75    		<artifactId>log4j</artifactId>
 76    		<version>1.2.15</version>
 77    		<exclusions>
 78    			<exclusion>
 79    				<groupId>javax.mail</groupId>
 80    				<artifactId>mail</artifactId>
 81    			</exclusion>
 82    			<exclusion>
 83    				<groupId>javax.jms</groupId>
 84    				<artifactId>jms</artifactId>
 85    			</exclusion>
 86    			<exclusion>
 87    				<groupId>com.sun.jdmk</groupId>
 88    				<artifactId>jmxtools</artifactId>
 89    			</exclusion>
 90    			<exclusion>
 91    				<groupId>com.sun.jmx</groupId>
 92    				<artifactId>jmxri</artifactId>
 93    			</exclusion>
 94    		</exclusions>
 95    		<scope>runtime</scope>
 96    	</dependency>
 97
 98    	<!-- @Inject -->
 99    	<dependency>
100    		<groupId>javax.inject</groupId>
101    		<artifactId>javax.inject</artifactId>
102    		<version>1</version>
103    	</dependency>
104
105    	<!-- Servlet -->
106    	<dependency>
107    		<groupId>javax.servlet</groupId>
108    		<artifactId>servlet-api</artifactId>
109    		<version>2.5</version>
110    		<scope>provided</scope>
111    	</dependency>
112    	<dependency>
113    		<groupId>javax.servlet.jsp</groupId>
114    		<artifactId>jsp-api</artifactId>
115    		<version>2.1</version>
116    		<scope>provided</scope>
117    	</dependency>
118    	<dependency>
119    		<groupId>javax.servlet</groupId>
120    		<artifactId>jstl</artifactId>
121    		<version>1.2</version>
122    	</dependency>
123
124    	<!-- Test -->
125    	<dependency>
126    		<groupId>junit</groupId>
127    		<artifactId>junit</artifactId>
128    		<version>4.7</version>
129    		<scope>test</scope>
130    	</dependency>
131    </dependencies>
132    <build>
133    	<plugins>
134    		<plugin>
135    			<artifactId>maven-eclipse-plugin</artifactId>
136    			<version>2.9</version>
137    			<configuration>
138    				<additionalProjectnatures>
139    					<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
140    				</additionalProjectnatures>
141    				<additionalBuildcommands>
142    					<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
143    				</additionalBuildcommands>
144    				<downloadSources>true</downloadSources>
145    				<downloadJavadocs>true</downloadJavadocs>
146    			</configuration>
147    		</plugin>
148    		<plugin>
149    			<groupId>org.apache.maven.plugins</groupId>
150    			<artifactId>maven-compiler-plugin</artifactId>
151    			<version>2.5.1</version>
152    			<configuration>
153    				<source>1.6</source>
154    				<target>1.6</target>
155    				<compilerArgument>-Xlint:all</compilerArgument>
156    				<showWarnings>true</showWarnings>
157    				<showDeprecation>true</showDeprecation>
158    			</configuration>
159    		</plugin>
160    		<plugin>
161    			<groupId>org.codehaus.mojo</groupId>
162    			<artifactId>exec-maven-plugin</artifactId>
163    			<version>1.2.1</version>
164    			<configuration>
165    				<mainClass>org.test.int1.Main</mainClass>
166    			</configuration>
167    		</plugin>
168    	</plugins>
169    </build>
170</project>

部署描述

当您从 STS 创建一个 Spring MVC 项目时,它会创建两个背景配置文件. 我已经清理了一点,并且只有一个春豆配置文件. 我的最终 web.xml 文件看起来像下面。

 1<?xml version="1.0" encoding="UTF-8"?>
 2<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
 3    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
 4    xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 5    
 6    <!-- Processes application requests -->
 7    <servlet>
 8    	<servlet-name>appServlet</servlet-name>
 9    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
10    	<init-param>
11    		<param-name>contextConfigLocation</param-name>
12    		<param-value>/WEB-INF/spring/spring.xml</param-value>
13    	</init-param>
14    	<load-on-startup>1</load-on-startup>
15    </servlet>
16    	
17    <servlet-mapping>
18    	<servlet-name>appServlet</servlet-name>
19    	<url-pattern>/</url-pattern>
20    </servlet-mapping>
21
22</web-app>

Spring Bean 配置文件

通常我们最后看看春节线路,但这次我们没有很多配置在春豆配置文件. 我们的最终春节线路.xml 文件看起来如下。

 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans:beans xmlns="https://www.springframework.org/schema/mvc"
 3    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
 4    xmlns:beans="https://www.springframework.org/schema/beans"
 5    xmlns:context="https://www.springframework.org/schema/context"
 6    xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
 7    	https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
 8    	https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
 9
10    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
11    
12    <!-- Enables the Spring MVC @Controller programming model -->
13    <annotation-driven />
14
15    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
16    <resources mapping="/resources/**" location="/resources/" />
17
18    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
19    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
20    	<beans:property name="prefix" value="/WEB-INF/views/" />
21    	<beans:property name="suffix" value=".jsp" />
22    </beans:bean>
23    
24    <beans:bean id="employeeValidator" class="com.journaldev.spring.form.validator.EmployeeFormValidator" />
25    
26    <beans:bean id="messageSource"
27    	class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
28    	<beans:property name="basename" value="classpath:message" />
29    	<beans:property name="defaultEncoding" value="UTF-8" />
30    </beans:bean>
31    
32    <context:component-scan base-package="com.journaldev.spring" />
33    
34</beans:beans>

唯一要注意的要点是EmployeeValidator豆,我们将注入控制器中的一个和messageSource豆,以便从资源包中读取本地化数据。

类型模型

我们在这个项目中有两个模型类 - 第一类我们将使用JSR-303注释和基于定制注释的验证器,第二类我们将只使用我们的验证器实现。

 1package com.journaldev.spring.form.model;
 2
 3import java.util.Date;
 4
 5import javax.validation.constraints.Max;
 6import javax.validation.constraints.Min;
 7import javax.validation.constraints.NotNull;
 8import javax.validation.constraints.Past;
 9import javax.validation.constraints.Size;
10
11import org.hibernate.validator.constraints.Email;
12import org.hibernate.validator.constraints.NotEmpty;
13import org.springframework.format.annotation.DateTimeFormat;
14
15import com.journaldev.spring.form.validator.Phone;
16
17public class Customer {
18
19    @Size(min=2, max=30) 
20    private String name;
21
22    @NotEmpty @Email
23    private String email;
24
25    @NotNull @Min(18) @Max(100)
26    private Integer age;
27
28    @NotNull
29    private Gender gender;
30
31    @DateTimeFormat(pattern="MM/dd/yyyy")
32    @NotNull @Past
33    private Date birthday;
34
35    @Phone
36    private String phone;
37
38    public enum Gender {
39    	MALE, FEMALE
40    }
41
42    public String getName() {
43    	return name;
44    }
45
46    public void setName(String name) {
47    	this.name = name;
48    }
49
50    public String getEmail() {
51    	return email;
52    }
53
54    public void setEmail(String email) {
55    	this.email = email;
56    }
57
58    public Integer getAge() {
59    	return age;
60    }
61
62    public void setAge(Integer age) {
63    	this.age = age;
64    }
65
66    public Gender getGender() {
67    	return gender;
68    }
69
70    public void setGender(Gender gender) {
71    	this.gender = gender;
72    }
73
74    public Date getBirthday() {
75    	return birthday;
76    }
77
78    public void setBirthday(Date birthday) {
79    	this.birthday = birthday;
80    }
81
82    public String getPhone() {
83    	return phone;
84    }
85
86    public void setPhone(String phone) {
87    	this.phone = phone;
88    }
89    
90}

请注意,我们正在使用 @Email、 @NotEmpty 和 @DateTimeFormat 注释,这些注释是 JSR-303 附加的,并由 Hibernate 验证器实现提供。 我们正在使用的 JSR-303 注释中有一些是 @Size、 @NotNull 等。

 1package com.journaldev.spring.form.model;
 2
 3public class Employee {
 4
 5    private int id;
 6    private String name;
 7    private String role;
 8    
 9    public int getId() {
10    	return id;
11    }
12    public void setId(int id) {
13    	this.id = id;
14    }
15    public String getName() {
16    	return name;
17    }
18    public void setName(String name) {
19    	this.name = name;
20    }
21    public String getRole() {
22    	return role;
23    }
24    public void setRole(String role) {
25    	this.role = role;
26    }
27    
28}

员工是标准的 java 棒,我们将使用我们的自定义验证器实现程序来验证表单。

定制验证器实施

Phone.java 代码:

 1package com.journaldev.spring.form.validator;
 2
 3import java.lang.annotation.Documented;
 4import java.lang.annotation.Retention;
 5import java.lang.annotation.Target;
 6import java.lang.annotation.ElementType;
 7import java.lang.annotation.RetentionPolicy;
 8
 9import javax.validation.Constraint;
10import javax.validation.Payload;
11
12@Documented
13@Constraint(validatedBy = PhoneValidator.class)
14@Target( { ElementType.METHOD, ElementType.FIELD })
15@Retention(RetentionPolicy.RUNTIME)
16public @interface Phone {
17
18    String message() default "{Phone}";
19
20    Class<?>[] groups() default {};
21
22    Class<? extends Payload>[] payload() default {};
23
24}

大部分是用 JSR-303 规格确认的锅炉板代码,最重要的部分是 @Constraint 注释,我们提供将用于验证的类,即PhoneValidator

 1package com.journaldev.spring.form.validator;
 2
 3import javax.validation.ConstraintValidator;
 4import javax.validation.ConstraintValidatorContext;
 5
 6public class PhoneValidator implements ConstraintValidator<Phone, String> {
 7
 8    @Override
 9    public void initialize(Phone paramA) {
10    }
11
12    @Override
13    public boolean isValid(String phoneNo, ConstraintValidatorContext ctx) {
14    	if(phoneNo == null){
15    		return false;
16    	}
17    	//validate phone numbers of format "1234567890"
18        if (phoneNo.matches("\\d{10}")) return true;
19        //validating phone number with -, . or spaces
20        else if(phoneNo.matches("\\d{3}[-\\.\\s]\\d{3}[-\\.\\s]\\d{4}")) return true;
21        //validating phone number with extension length from 3 to 5
22        else if(phoneNo.matches("\\d{3}-\\d{3}-\\d{4}\\s(x|(ext))\\d{3,5}")) return true;
23        //validating phone number where area code is in braces ()
24        else if(phoneNo.matches("\\(\\d{3}\\)-\\d{3}-\\d{4}")) return true;
25        //return false if nothing matches the input
26        else return false;
27    }
28
29}

我們的 JSR-303 規格驗證器實施應實施「javax.validation.ConstraintValidator」接口. 如果我們正在使用一些資源,如 DataSource,我們可以將其初始化為「initialize()」方法。 驗證方法是「isValid」並且如果資料有效,它會返回真實,否則它應該返回虛假。 如果您是新的正規表現,您可以閱讀更多關於它在 Java 正規表現教程. EmployeeFormValidator.java 類碼:

 1package com.journaldev.spring.form.validator;
 2
 3import org.springframework.validation.Errors;
 4import org.springframework.validation.ValidationUtils;
 5import org.springframework.validation.Validator;
 6
 7import com.journaldev.spring.form.model.Employee;
 8
 9public class EmployeeFormValidator implements Validator {
10
11    //which objects can be validated by this validator
12    @Override
13    public boolean supports(Class<?> paramClass) {
14    	return Employee.class.equals(paramClass);
15    }
16
17    @Override
18    public void validate(Object obj, Errors errors) {
19    	ValidationUtils.rejectIfEmptyOrWhitespace(errors, "id", "id.required");
20    	
21    	Employee emp = (Employee) obj;
22    	if(emp.getId() <=0){
23    		errors.rejectValue("id", "negativeValue", new Object[]{"'id'"}, "id can't be negative");
24    	}
25    	
26    	ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "name.required");
27    	ValidationUtils.rejectIfEmptyOrWhitespace(errors, "role", "role.required");
28    }
29}

EmployeeFormValidator 是 Spring Framework 特定的验证执行程序。 Spring Framework 支持() 方法实现,以了解可以使用此验证的对象。我们实施 validate() 方法,并在任何领域验证失败时添加错误。 Spring 提供 `org.springframework.validation.ValidationUtils' 实用类用于基本验证,如 null 或 empty。一旦这个方法返回, Spring Framework 将 Errors 对象绑定到我们在控制器处理方法中使用的 BindingResult 对象中。 请注意,‘ValidationUtils.rejectIfEmptyOrWhitespace()’ 最后一个论点是消息资源的关键名称。 这样,我们可以向用户提供本地化的错误消息。

控制班级

我们有两个控制器类,一个用于基于注释的表单验证,另一个用于我们的自定义验证器。

 1package com.journaldev.spring.form.controllers;
 2
 3import java.util.HashMap;
 4import java.util.Map;
 5
 6import javax.validation.Valid;
 7
 8import org.slf4j.Logger;
 9import org.slf4j.LoggerFactory;
10import org.springframework.stereotype.Controller;
11import org.springframework.ui.Model;
12import org.springframework.validation.BindingResult;
13import org.springframework.web.bind.annotation.RequestMapping;
14import org.springframework.web.bind.annotation.RequestMethod;
15
16import com.journaldev.spring.form.model.Customer;
17
18@Controller
19public class CustomerController {
20
21    private static final Logger logger = LoggerFactory
22    		.getLogger(CustomerController.class);
23    
24    private Map<String, Customer> customers = null;
25    
26    public CustomerController(){
27    	customers = new HashMap<String, Customer>();
28    }
29
30    @RequestMapping(value = "/cust/save", method = RequestMethod.GET)
31    public String saveCustomerPage(Model model) {
32    	logger.info("Returning custSave.jsp page");
33    	model.addAttribute("customer", new Customer());
34    	return "custSave";
35    }
36
37    @RequestMapping(value = "/cust/save.do", method = RequestMethod.POST)
38    public String saveCustomerAction(
39    		@Valid Customer customer,
40    		BindingResult bindingResult, Model model) {
41    	if (bindingResult.hasErrors()) {
42    		logger.info("Returning custSave.jsp page");
43    		return "custSave";
44    	}
45    	logger.info("Returning custSaveSuccess.jsp page");
46    	model.addAttribute("customer", customer);
47    	customers.put(customer.getEmail(), customer);
48    	return "custSaveSuccess";
49    }
50
51}

当我们使用基于注释的表单验证时,我们只需要在我们的控制器处理方法实现中做出小小的变化,以便它工作。 首先,我们需要注释我们想要用@Valid注释验证的模型对象。 然后我们需要在方法中有BindingResult论点,春天照顾它填充错误消息。 处理器方法的逻辑非常简单,如果有任何错误,我们正在与同一页面响应,否则我们正在将用户重定向到成功页面。 另一个重要点要注意的是,我们正在将客户属性添加到模型中,这是必要的,以便春天知道在表单页中使用哪个模型对象。 如果我们不这样做,对象绑定到表单数据不会发生,我们的形式验证不会起作用

 1package com.journaldev.spring.form.controllers;
 2
 3import java.util.HashMap;
 4import java.util.Map;
 5
 6import org.slf4j.Logger;
 7import org.slf4j.LoggerFactory;
 8import org.springframework.beans.factory.annotation.Autowired;
 9import org.springframework.beans.factory.annotation.Qualifier;
10import org.springframework.stereotype.Controller;
11import org.springframework.ui.Model;
12import org.springframework.validation.BindingResult;
13import org.springframework.validation.Validator;
14import org.springframework.validation.annotation.Validated;
15import org.springframework.web.bind.WebDataBinder;
16import org.springframework.web.bind.annotation.InitBinder;
17import org.springframework.web.bind.annotation.ModelAttribute;
18import org.springframework.web.bind.annotation.RequestMapping;
19import org.springframework.web.bind.annotation.RequestMethod;
20
21import com.journaldev.spring.form.model.Employee;
22
23@Controller
24public class EmployeeController {
25
26    private static final Logger logger = LoggerFactory
27    		.getLogger(EmployeeController.class);
28
29    private Map<Integer, Employee> emps = null;
30
31    @Autowired
32    @Qualifier("employeeValidator")
33    private Validator validator;
34
35    @InitBinder
36    private void initBinder(WebDataBinder binder) {
37    	binder.setValidator(validator);
38    }
39
40    public EmployeeController() {
41    	emps = new HashMap<Integer, Employee>();
42    }
43
44    @ModelAttribute("employee")
45    public Employee createEmployeeModel() {
46    	// ModelAttribute value should be same as used in the empSave.jsp
47    	return new Employee();
48    }
49
50    @RequestMapping(value = "/emp/save", method = RequestMethod.GET)
51    public String saveEmployeePage(Model model) {
52    	logger.info("Returning empSave.jsp page");
53    	return "empSave";
54    }
55
56    @RequestMapping(value = "/emp/save.do", method = RequestMethod.POST)
57    public String saveEmployeeAction(
58    		@ModelAttribute("employee") @Validated Employee employee,
59    		BindingResult bindingResult, Model model) {
60    	if (bindingResult.hasErrors()) {
61    		logger.info("Returning empSave.jsp page");
62    		return "empSave";
63    	}
64    	logger.info("Returning empSaveSuccess.jsp page");
65    	model.addAttribute("emp", employee);
66    	emps.put(employee.getId(), employee);
67    	return "empSaveSuccess";
68    }
69}

对于使用自定义验证器,我们首先需要将其注入控制器类别。我们正在使用(/community/tutorials/spring-autowired-annotation Spring bean autowire by name, type, constructor, Autowired and Qualifier annotations example)来实现这一点,使用@Autowired@Qualifier注释。接下来,我们需要有一个方法,将WebDataBinder作为论点,我们将我们的自定义验证器设置为使用。

表格验证 错误消息 资源包

现在是时候看看我们的资源包,在那里我们有不同的类型的消息用于验证错误。

 1#application defined error messsages
 2id.required=Employee ID is required
 3name.required=Employee Name is required
 4role.required=Employee Role is required
 5negativeValue={0} can't be negative or zero
 6
 7#Spring framework error messages to be used when conversion from form data to bean fails
 8typeMismatch.int={0} Value must be an integer
 9typeMismatch.java.lang.Integer={0} must be an integer
10typeMismatch={0} is of invalid format
11
12#application messages for annotations, {ValidationClass}.{modelObjectName}.{field}
13#the {0} is field name, other fields are in alphabatical order, max and then min  
14Size.customer.name=Customer {0} should be between {2} and {1} characters long
15NotEmpty.customer.email=Email is a required field
16NotNull.customer.age=Customer {0} should be in years
17
18#Generic annotation class messages
19Email=Email address is not valid
20NotNull=This is a required field
21NotEmpty=This is a required field
22Past=Date should be Past
23
24#Custom validation annotation
25Phone=Invalid format, valid formats are 1234567890, 123-456-7890 x1234

我已经在评论中提供了消息的关键细节,所以我会在这里跳过它们。这里唯一要注意的要点是消息将被搜索的方式,第一个关键名 {ValidationClass}.{modelObjectName}.{field}被搜索,如果没有找到,那么 {ValidationClass}.{modelName}被搜索。如果缺少了,那么最后 {ValidationClass} 键被搜索。如果没有找到,则将返回提供的默认消息。 阅读更多关于资源消息的信息在 春季定位示例

显示有形状和错误的页面

由于我们正在使用 Spring Framework 验证实现,我们将不得不使用 Spring Form 标签来获取错误并设置表单标本和变量名称。

 1<%@ page language="java" contentType="text/html; charset=UTF-8"
 2    pageEncoding="UTF-8"%>
 3<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
 4<%@ taglib uri="https://www.springframework.org/tags/form"
 5    prefix="springForm"%>
 6<html>
 7<head>
 8<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 9<title>Customer Save Page</title>
10<style>
11.error {
12    color: #ff0000;
13    font-style: italic;
14    font-weight: bold;
15}
16</style>
17</head>
18<body>
19
20    <springForm:form method="POST" commandName="customer"
21    	action="save.do">
22    	<table>
23    		<tr>
24    			<td>Name:</td>
25    			<td><springForm:input path="name" /></td>
26    			<td><springForm:errors path="name" cssClass="error" /></td>
27    		</tr>
28    		<tr>
29    			<td>Email:</td>
30    			<td><springForm:input path="email" /></td>
31    			<td><springForm:errors path="email" cssClass="error" /></td>
32    		</tr>
33    		<tr>
34    			<td>Age:</td>
35    			<td><springForm:input path="age" /></td>
36    			<td><springForm:errors path="age" cssClass="error" /></td>
37    		</tr>
38    		<tr>
39    			<td>Gender:</td>
40    			<td><springForm:select path="gender">
41    					<springForm:option value="" label="Select Gender" />
42    					<springForm:option value="MALE" label="Male" />
43    					<springForm:option value="FEMALE" label="Female" />
44    				</springForm:select></td>
45    			<td><springForm:errors path="gender" cssClass="error" /></td>
46    		</tr>
47    		<tr>
48    			<td>Birthday:</td>
49    			<td><springForm:input path="birthday" placeholder="MM/dd/yyyy"/></td>
50    			<td><springForm:errors path="birthday" cssClass="error" /></td>
51    		</tr>
52    		<tr>
53    			<td>Phone:</td>
54    			<td><springForm:input path="phone" /></td>
55    			<td><springForm:errors path="phone" cssClass="error" /></td>
56    		</tr>
57    		<tr>
58    			<td colspan="3"><input type="submit" value="Save Customer"></td>
59    		</tr>
60    	</table>
61
62    </springForm:form>
63
64</body>
65</html>

「commandName="customer"」用于设置表单对象曝光的模型属性名称。它的默认值是「command」默认,因此我们应该将其设置为我们在控制器类中使用的模型属性名称。「springForm:errors」用于渲染页面渲染时发现的错误,如果有,则用于渲染。「path」属性用于定义用于数据绑定的对象属性。代码的其余部分是标准的HTML和一些CSS错误来编写消息。

 1<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
 2<%@ taglib prefix="fmt" uri="https://java.sun.com/jsp/jstl/fmt" %>
 3
 4<%@ page session="false" %>
 5<html>
 6<head>
 7    <title>Customer Saved Successfully</title>
 8</head>
 9<body>
10<h3>
11    Customer Saved Successfully.
12</h3>
13
14<strong>Customer Name:${customer.name}</strong><br>
15<strong>Customer Email:${customer.email}</strong><br>
16<strong>Customer Age:${customer.age}</strong><br>
17<strong>Customer Gender:${customer.gender}</strong><br>
18<strong>Customer Birthday:<fmt:formatDate value="${customer.birthday}" type="date" /></strong><br>
19
20</body>
21</html>

简单的 JSP 页面显示客户值,如果没有验证错误,并返回此页面作为响应。

 1<%@ page language="java" contentType="text/html; charset=UTF-8"
 2    pageEncoding="UTF-8"%>
 3<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
 4<%@ taglib uri="https://www.springframework.org/tags/form"
 5    prefix="springForm"%>
 6<html>
 7<head>
 8<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 9<title>Employee Save Page</title>
10<style>
11.error {
12    color: #ff0000;
13    font-style: italic;
14    font-weight: bold;
15}
16</style>
17</head>
18<body>
19
20    <springForm:form method="POST" commandName="employee"
21    	action="save.do">
22    	<table>
23    		<tr>
24    			<td>Employee ID:</td>
25    			<td><springForm:input path="id" /></td>
26    			<td><springForm:errors path="id" cssClass="error" /></td>
27    		</tr>
28    		<tr>
29    			<td>Employee Name:</td>
30    			<td><springForm:input path="name" /></td>
31    			<td><springForm:errors path="name" cssClass="error" /></td>
32    		</tr>
33    		<tr>
34    			<td>Employee Role:</td>
35    			<td><springForm:select path="role">
36    					<springForm:option value="" label="Select Role" />
37    					<springForm:option value="ceo" label="CEO" />
38    					<springForm:option value="developer" label="Developer" />
39    					<springForm:option value="manager" label="Manager" />
40    				</springForm:select></td>
41    			<td><springForm:errors path="role" cssClass="error" /></td>
42    		</tr>
43    		<tr>
44    			<td colspan="3"><input type="submit" value="Save"></td>
45    		</tr>
46    	</table>
47
48    </springForm:form>
49
50</body>
51</html>

点击下载:jsp 文件:

 1<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
 2<%@ page session="false" %>
 3<html>
 4<head>
 5    <title>Employee Saved Successfully</title>
 6</head>
 7<body>
 8<h3>
 9    Employee Saved Successfully.
10</h3>
11
12<strong>Employee ID:${emp.id}</strong><br>
13<strong>Employee Name:${emp.name}</strong><br>
14<strong>Employee Role:${emp.role}</strong><br>
15
16</body>
17</html>

测试春季MVC表单验证应用程序

Our application is ready to deploy and run some tests, deploy it in your favorite servlet container. I am using Apache Tomcat 7 and below images show some of the pages with validation error messages. Based on your input data, you might get different error messages too. Spring Validator Example Spring Validation Example Spring Form Validation example That's all for Spring MVC Form validation with different ways and using resource bundles for localized error messages. You can download the sample project from below link and play around with it to learn more.

[下载《春季法案验证项目》(LINK0)]

Published At
Categories with 技术
Tagged with
comments powered by Disqus