[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;

@Component
public 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>

即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM