1.使用接口Validator
需要entity controller validator web.xml springmvc.xml
login.jsp
<body>
<form:form action="loginHander" method="post" commandName="user">
用户名:<form:input path="userName"/><form:errors path="userName"/>
密码:<form:input path="userPwd"/><form:errors path="userPwd"/>
<input type="submit" value="提交">
</form:form>
</body>
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.hellojava"/>
<mvc:annotation-driven validator="userValidator"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
validator层
Supports方法用于判断当前的Validator实现类是否支持校验当前需要校验的实体类,只有当supports方法的返回结果为true的时候,该Validator接口实现类的validate方法才会被调用来对当前需要校验的实体类进行校验。
在supports方法中定义了该UserValidator只支持对User对象进行校验。在validate方法中我们校验了User对象的userName和userPwd不为empty的情况,这里的empty包括null和空字符串两种情况。ValidationUtils类是Spring中提供的一个工具类。Errors就是Spring用来存放错误信息的对象。
我们已经定义了一个对User类进行校验的UserValidator了,但是这个时候UserValidator还不能对User对象进行校验,因为我们还没有告诉Spring应该使用UserValidator来校验User对象。在SpringMVC中我们可以使用DataBinder来设定当前Controller需要使用的Validator
package com.hellojava.validator;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.hellojava.entity.User;
@Component("userValidator")
public class UserValidator implements Validator{
//验证哪些类型(User)
@Override
public boolean supports(Class<?> c) {
return User.class.equals(c);
}
@Override
public void validate(Object obj, Errors error) {
//验证工具栏
ValidationUtils.rejectIfEmpty(error,"userName",null,"用户名不能为空");
ValidationUtils.rejectIfEmpty(error, "userPwd", null, "密码不能为空");
}
}
controller层
package com.hellojava.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import com.hellojava.entity.User;
import com.hellojava.validator.UserValidator;
@Controller
public class UserController {
@InitBinder
public void initValidator(WebDataBinder binder){
binder.setValidator(new UserValidator());
}
@RequestMapping("/login")
public String loginView(ModelMap model){
model.addAttribute("user", new User());
return "login";
}
@RequestMapping("/loginHander")
public String loginHander(@Valid User user,BindingResult result){
if(result.hasErrors()){
return "login";
}
System.out.println(user);
return "index";
}
}
我们定义了一个UserController,该Controller有一个处理login操作的处理器方法loginHander,它需要接收客户端发送的一个User对象,我们就是要利用前面的UserValidator对该User对象进行校验。首先我们可以看到我们login方法接收的参数user是用@Valid进行标注的,这里的@Valid是定义在JSR-303标准中的,我这里使用的是Hibernate Validation对它的实现。这里我们必须使用@Valid标注我们需要校验的参数user,否则Spring不会对它进行校验。另外我们的处理器方法必须给定包含Errors的参数,这可以是Errors本身,也可以是它的子类BindingResult,使用了Errors参数就是告诉Spring关于表单对象数据校验的错误将由我们自己来处理,否则Spring会直接抛出异常,而且这个参数是必须紧挨着@Valid参数的,即必须紧挨着需要校验的参数,这就意味着我们有多少个@Valid参数就需要有多少个对应的Errors参数,它们是一一对应的。
前面有提到我们可以通过DataBinder来指定需要使用的Validator,我们可以看到在上面代码中我们通过@InitBinder标记的方法initBinder设置了当前Controller需要使用的Validator是UserValidator。这样当我们请求处理器方法login时就会使用DataBinder设定的UserValidator来校验当前的表单对象User,首先会通过UserValidator的supports方法判断其是否支持User对象的校验,若支持则调用UserValidator的validate方法,并把相关的校验信息存放到当前的Errors对象中。接着我们就可以在我们的处理器方法中根据是否有校验异常信息来做不同的操作。在上面代码中我们定义了在有异常信息的时候就跳转到登陆页面。这样我们就可以在登陆页面上通过errors标签来展示这些错误信息了。
我们知道在Controller类中通过@InitBinder标记的方法只有在请求当前Controller的时候才会被执行,所以其中定义的Validator也只能在当前Controller中使用,如果我们希望一个Validator对所有的Controller都起作用的话,我们可以通过WebBindingInitializer的initBinder方法来设定了。另外,在SpringMVC的配置文件中通过mvc:annotation-driven的validator属性也可以指定全局的Validator。
2.使用JSR-303 Validation进行验证+格式化
需要web.xml springmvc.xml entity controller
可以更改提示的内容
message_zh_CN.properties文件里面
NotEmpty.user.userName=\u60A8\u8F93\u5165\u7684\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A
注解.对象.属性
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.hellojava"/>
<mvc:annotation-driven/>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="message"></property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
controller层
package com.hellojava.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import com.hellojava.entity.User;
@Controller
public class UserController {
/*@InitBinder
public void initValidator(WebDataBinder binder){
binder.setValidator(new UserValidator());
}*/
@RequestMapping("/login")
public String loginView(ModelMap model){
model.addAttribute("user", new User());
return "login";
}
@RequestMapping("/loginHander")
public String loginHander(@Valid User user,BindingResult result){
if(result.hasErrors()){
return "login";
}
return "index";
}
}
entity
import java.io.Serializable;
import java.util.Date;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
public class User implements Serializable{
private int userId;
@NotEmpty
private String userName;
@NotEmpty
@Length(min=2,max=10)
private String userPwd;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date userBirth=new Date();