首页 > 代码库 > [Spring MVC] - InitBinder验证

[Spring MVC] - InitBinder验证

Spring MVC使用InitBinder验证:

使用InitBinder做验证的情况一般会在此Controller中提交的数据需要有一些是业务性质的,也即比较复杂的验证情况下才会使用。大部份简单的表单验证,使用annotation验证即可以解决。

Annotation验证使用方法可参见:http://www.cnblogs.com/HD/p/4123146.html

这里需要注意的一点:InitBinder和Annotation两种验证只能二选一,如果使用了InitBinder,就不能使用Annotation验证。

 

前面的web.xml和spring.xml的配置就不再重复,可参见上面链接中的配置。一模一样。

直接上代码:

 

1、User5 model实体类

package com.my.controller.bean;import java.util.Date;public class User5 {        private long id;    private String name;    private String password;    private Date createTime;    private int age;        public long getId() {        return id;    }    public void setId(long id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}

 

2、新增一个Validator:

package com.my.controller.validator;import org.springframework.stereotype.Component;import org.springframework.validation.Errors;import org.springframework.validation.ValidationUtils;import org.springframework.validation.Validator;import com.my.controller.bean.User5;@Componentpublic class TestValidator implements Validator {    @Override    public boolean supports(Class<?> paramClass) {        return User5.class.equals(paramClass);    }    @Override    public void validate(Object obj, Errors errors) {        User5 user = (User5) obj;                ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "valid.name", null, "");                if(user.getAge() < 18) {            errors.rejectValue("age", "valid.ageMin", new Object[]{"age" ,18}, "年龄不能小于{1}岁");        }    }}

这里需要加入@Component,注入DI

 

3、Controller

package com.my.controller;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import javax.validation.Valid;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Controller;import org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;import org.springframework.validation.Validator;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 org.springframework.web.servlet.ModelAndView;import com.my.controller.bean.User5;@Controller@RequestMapping(value="binder")public class TestInitBinderController {        @Autowired    @Qualifier(value="testValidator")    private Validator validator;        @InitBinder    private void initBinder(WebDataBinder binder) {        binder.setValidator(validator);    }        @RequestMapping(method=RequestMethod.GET)    public String index() {        return "/TestInitBinder/index";    }        @RequestMapping(value="add", method=RequestMethod.POST)    public ModelAndView add(@ModelAttribute @Valid User5 user, BindingResult result) {        ModelAndView view = new ModelAndView("TestInitBinder/index");        view.addObject("user", user);                if(result.hasErrors()) {            List<FieldError> errs = result.getFieldErrors();            Map<String, String> mapErrors = new LinkedHashMap<String, String>();            for(FieldError err : errs) {                System.out.println("ObjectName:" + err.getObjectName() + "\tFieldName:" + err.getField()                        + "\tFieldValue:" + err.getRejectedValue() + "\tMessage:" + err.getDefaultMessage());                mapErrors.put(err.getField(), err.getDefaultMessage());                view.addObject("errors", mapErrors);            }                        return view;        }                return view;    }}

把Validator注入到Controller中。

事实上,使用InitBinder,在add controller中的err.getDefaultMessage()方法是取不到对应正确的message的。可以看最后的输入打印结果。

 

4、View

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %><%@ taglib prefix="st" uri="http://www.springframework.org/tags" %><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Init binder</title></head><body>    <form:form action="/TestSpringMvc1/binder/add" method="post" modelAttribute="user5">        User name:<input type="text" id="name" name="name" value="${user.name}" /><br/>        Password:<input type="text" id="password" name="password" value="${user.password}" /><br/>        Age:<input type="text" id="age" name="age" value="${user.age}" /><br/>        <input type="submit" value="Add"/>        <hr/>        Error:<br/>        <form:errors path="*"></form:errors>    </form:form></body></html>

注意,这里只能使用<form:errors />来取得错误信息,且,这个<form:errors/>一定要在<form:form/>当中。

 

5、结果测试

点击Add button:

 

打印输出:

可以看到,这里取不到错误的正确信息


 

 

事实上,在一个非常复杂表单页面,里头所提交的数据验证有一定的业务逻辑性时,InitBinder应该都不多用,因为很多时候我们可以使用一个Map,把errors插入进去,在页面读取即可。比如:

Map<String, String> errors;errors.add("name", "user name can NOT be empty!");::

页面中只需要使用:

<span style="color:red;">${errors.name}<span>

即可。

[Spring MVC] - InitBinder验证