Fork me on GitHub
余鸢

Spring MVC验证

Spring MVC Form Validation与Bean Validation API

此示例显示如何使用Java注释在没有任何xml的情况下使用Bean Validation API验证Spring MVC中的表单。 用户将被建议输入他们的注册数据,验证者将检查其有效性。

首先在项目中添加以下依赖项:

1
2
3
4
dependencies {
compile group: 'javax.validation', name: 'validation-api', version: '1.1.0.Final'
compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.2.4.Final'
}

创建模型类

创建模型类User如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import org.hibernate.validator.constraints.Email;
import org.springframework.format.annotation.DateTimeFormat;
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 java.util.Date;
public class User {
@NotNull(message = "Please input your email.")
@Email(message = "Email format is wrong.")
private String email;
@NotNull(message = "{user.password.notNull}")
@Size(min = 8, max = 16, message = "{user.password.size}")
private String password;
@NotNull(message = "{user.age.notNull}")
@Min(18)
@Max(100)
private Integer age;
@NotNull(message = "{user.birthday.notNull}")
@DateTimeFormat(pattern = "dd.MM.yyyy")
@Past(message = "{user.birthday.past}")
private Date birthday;
// getters, setters
}

这里使用一些JSR 303注释:@NotNull@Size@Min@Max@Past以及由hibernate验证器实现提供的一些附加注释:@Email@DateTimeFormat

请注意,在其注释中指定了email 字段的错误消息。 而在messages.properties文件中指定password,age 和birthday 字段的错误消息,以便演示验证错误消息的外部化。 这个文件应放在resources文件夹下:

1
2
3
4
5
6
7
user.password.notNull = Password field cannot be empty.
user.password.size = Password must be between {min} and {max} characters in length.
user.age.notNull = Please enter your age.
user.birthday.notNull = Please enter your birthday.
user.birthday.past = That's impossible.
typeMismatch=Please use dd.MM.yyyy format

对于messageSource()bean.setBasename("classpath:messages"); 代码和validator() bean也必须配置以及注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
@PropertySource("application.properties")
public class AppConfig extends WebMvcConfigurerAdapter {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
bean.setBasename("classpath:messages");
bean.setDefaultEncoding("UTF-8");
return bean;
}
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
@Override
public Validator getValidator() {
return validator();
}
}

另外配置类mu使用@PropertySource(“application.properties”)注释,并且必须将jsp页面的路径添加到此文件,如下所示:

1
2
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

创建FormController类

现在在controller 类中,通过javax.validation包中的@Valid注释注释正在备份表单的模型对象。

Spring MVC将使用@Valid注释来验证模型对象,并将其属性与使用Spring的表单标签的JSP表单的输入绑定。 任何约束违反将暴露为BindingResult对象中的错误,因此我们可以在控制器的方法中检查违例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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 javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@Controller
public class FormController {
private Map<String, User> users = null;
public FormController() {
users = new HashMap<String, User>();
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public String viewRegister(Map<String, Object> model) {
User user = new User();
model.put("user", user);
return "register";
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String doRegister(@Valid User user, BindingResult result, Model model) {
if (result.hasErrors()) {
return "register";
}
model.addAttribute("user", user);
users.put(user.getEmail(), user);
return "registerSuccess";
}
}

创建JSP输入表单

添加具有以下内容的register.jsp文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User Form Page</title>
<style>
.error {
color: #ff0000;
font-weight: bold;
}
</style>
</head>
<body>
<form:form method="POST" commandName="user" action="register">
<table>
<tr>
<td>Email:</td>
<td><form:input path="email" placeholder="Email"/></td>
<td><form:errors path="email" cssClass="error" /></td>
</tr>
<tr>
<td>Password:</td>
<td><form:password path="password" placeholder="Password"/></td>
<td><form:errors path="password" cssClass="error" /></td>
</tr>
<tr>
<td>Age:</td>
<td><form:input path="age" placeholder="Age"/></td>
<td><form:errors path="age" cssClass="error" /></td>
</tr>
<tr>
<td>Birthday:</td>
<td><form:input path="birthday" placeholder="dd.MM.yyyy"/></td>
<td><form:errors path="birthday" cssClass="error" /></td>
</tr>
<tr>
<td colspan="3"><input type="submit" value="Register"></td>
</tr>
</table>
</form:form>
</body>
</html>

通常,当发生任何验证错误时,我们会将输入表单返回给用户。 在JSP表单中,我们可以使用Spring的形式错误标记(如 )显示验证错误消息。

创建JSP Success页面

将显示registerSuccess.jsp页面,以防用户输入所有数据有效。 这里是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page session="false" %>
<html>
<head>
<title>Success</title>
</head>
<body>
<h3>User Registered Successfully.</h3>
<strong>User Email: ${user.email}</strong><br>
<strong>User Age: ${user.age}</strong><br>
<strong>User Birthday: <fmt:formatDate value="${user.birthday}" type="date" pattern="dd.MM.yyyy"/></strong><br>
</body>
</html>

启动应用程序,转到http://localhost:8080/