4.16.2、数据验证
java代码:
- package org.springframework.validation;
- public interface Errors {
- //=========================全局错误消息(验证/绑定对象全局的)=============================
- //注册一个全局的错误码()
- void reject(String errorCode);
- //注册一个全局的错误码,当根据errorCode没有找到相应错误消息时,使用defaultMessage作为错误消息
- void reject(String errorCode, String defaultMessage);
- //注册一个全局的错误码,当根据errorCode没有找到相应错误消息时(带错误参数的),使用defaultMessage作为错误消息
- void reject(String errorCode, Object[] errorArgs, String defaultMessage);
- //=========================全局错误消息(验证/绑定整个对象的)=============================
- //=========================局部错误消息(验证/绑定对象字段的)=============================
- //注册一个对象字段的错误码,field指定验证失败的字段名
- void rejectValue(String field, String errorCode);
- void rejectValue(String field, String errorCode, String defaultMessage);
- void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage);
- //=========================局部错误消息(验证/绑定对象字段的)=============================
- boolean hasErrors(); 是否有错误
- boolean hasGlobalErrors(); //是否有全局错误
- boolean hasFieldErrors(); //是否有字段错误
- Object getFieldValue(String field); //返回当前验证通过的值,或验证失败时失败的值;
- }
java代码:
- package cn.javass.chapter4.web.controller;
- //省略import
- public class ErrorController extends AbstractCommandController {
- public ErrorController() {
- setCommandClass(DataBinderTestModel.class);
- setCommandName("command");
- }
- @Override
- protected ModelAndView handle(HttpServletRequest req, HttpServletResponse resp, Object command, BindException errors) throws Exception {
- //表示用户名不为空
- errors.reject("username.not.empty");
- //带有默认错误消息
- errors.reject("username.not.empty1", "用户名不能为空1");
- //带有参数和默认错误消息
- errors.reject("username.length.error", new Object[]{5, 10});
- //得到错误相关的模型数据
- Map model = errors.getModel();
- return new ModelAndView("bindAndValidate/error", model);
- }
- }
errors.reject("username.not.empty"):注册全局错误码“username.not.empty”,我们必须提供messageSource来提供错误码“username.not.empty”对应的错误信息(如果没有会抛出NoSuchMessageException异常);
java代码:
- <bean id="messageSource"
- class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
- <property name="basename" value="classpath:messages"/>
- <property name="fileEncodings" value="utf-8"/>
- <property name="cacheSeconds" value="120"/>
- </bean>
- <bean name="/error" class="cn.javass.chapter4.web.controller.ErrorController"/>
java代码:
- username.not.empty=用户名不能为空
- username.length.error=用户名长度不合法,长度必须在{0}到{1}之间
java代码:
- <%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
- <!-- 表单的默认命令对象名为command -->
- <form:form commandName="command">
- <form:errors path="*"></form:errors>
- </form:form>
java代码:
- package cn.javass.chapter4.web.controller;
- //省略import
- public class DataBinderErrorTestController extends SimpleFormController {
- public DataBinderErrorTestController() {
- setCommandClass(DataBinderTestModel.class);
- setCommandName("dataBinderTest");
- }
- @Override
- protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception {
- //如果表单提交有任何错误都会再回到表单展示页面
- System.out.println(errors);
- return super.showForm(request, response, errors);
- }
- @Override
- protected void doSubmitAction(Object command) throws Exception {
- System.out.println(command); //表单提交成功(数据绑定成功)进行功能处理
- }
- @Override
- protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
- super.initBinder(request, binder);
- //注册自定义的属性编辑器
- //1、日期
- DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- CustomDateEditor dateEditor = new CustomDateEditor(df, true);
- //表示如果命令对象有Date类型的属性,将使用该属性编辑器进行类型转换
- binder.registerCustomEditor(Date.class, dateEditor);
- //自定义的电话号码编辑器
- binder.registerCustomEditor(PhoneNumberModel.class, new PhoneNumberEditor());
- }
- }
java代码:
- <bean name="/dataBindError"
- class="cn.javass.chapter4.web.controller.DataBinderErrorTestController">
- <property name="formView" value="bindAndValidate/input"/>
- <property name="successView" value="bindAndValidate/success"/>
- </bean>
java代码:
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
- <!-- 表单的命令对象名为dataBinderTest -->
- <form:form commandName="dataBinderTest">
- <form:errors path="*" cssStyle="color:red"></form:errors><br/><br/>
- bool:<form:input path="bool"/><br/>
- phoneNumber:<form:input path="phoneNumber"/><br/>
- date:<form:input path="date"/><br/>
- <input type="submit" value="提交"/>
- </form:form>
java代码:
- org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 3 errors
- Field error in object 'dataBinderTest' on field 'bool': rejected value [www]; codes [typeMismatch.dataBinderTest.bool,typeMismatch.bool,typeMismatch.boolean,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.bool,bool]; arguments []; default message [bool]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'boolean' for property 'bool'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [www]]
- Field error in object 'dataBinderTest' on field 'date': rejected value [123]; codes [typeMismatch.dataBinderTest.date,typeMismatch.date,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.date,date]; arguments []; default message [date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'date'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "123"]
- Field error in object 'dataBinderTest' on field 'phoneNumber': rejected value [123]; codes [typeMismatch.dataBinderTest.phoneNumber,typeMismatch.phoneNumber,typeMismatch.cn.javass.chapter4.model.PhoneNumberModel,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dataBinderTest.phoneNumber,phoneNumber]; arguments []; default message [phoneNumber]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'cn.javass.chapter4.model.PhoneNumberModel' for property 'phoneNumber'; nested exception is java.lang.IllegalArgumentException: 类型转换失败,需要格式[010-12345678],但格式是[123]]
java代码:
- typeMismatch.dataBinderTest.date=您输入的数据格式错误,请重新输入(格式:2012-03-19 22:17:17)
- #typeMismatch.date=2
- #typeMismatch.java.util.Date=3
- #typeMismatch=4
java代码:
- package org.springframework.validation;
- public interface Validator {
- boolean supports(Class<?> clazz);
- void validate(Object target, Errors errors);
- }
java代码:
- package cn.javass.chapter4.web.controller.support.validator;
- //省略import
- public class UserModelValidator implements Validator {
- private static final Pattern USERNAME_PATTERN = Pattern.compile("[a-zA-Z]\\w{4,19}");
- private static final Pattern PASSWORD_PATTERN = Pattern.compile("[a-zA-Z0-9]{5,20}");
- private static final Set<String> FORBINDDDEN_WORD_SET = new HashSet<String>();
- static {
- FORBINDDDEN_WORD_SET.add("fuc k"); //删掉空格
- FORBINDDDEN_WORD_SET.add("admin");
- }
- @Override
- public boolean supports(Class<?> clazz) {
- return UserModel.class == clazz;//表示只对UserModel类型的目标对象实施验证
- }
- @Override
- public void validate(Object target, Errors errors) {
- //这个表示如果目标对象的username属性为空,则表示错误(简化我们手工判断是否为空)
- ValidationUtils.rejectIfEmpty(errors, "username", "username.not.empty");
- UserModel user = (UserModel) target;
- if(!USERNAME_PATTERN.matcher(user.getUsername()).matches()) {
- errors.rejectValue("username", "username.not.illegal");//如果用户名不合法
- }
- for(String forbiddenWord : FORBINDDDEN_WORD_SET) {
- if(user.getUsername().contains(forbiddenWord)) {
- errors.rejectValue("username", "username.forbidden", new Object[]{forbiddenWord}, "您的用户名包含非法关键词");//用户名包含屏蔽关键字
- break;
- }
- }
- if(!PASSWORD_PATTERN.matcher(user.getPassword()).matches()) {
- errors.rejectValue("password","password.not.illegal", "密码不合法");//密码不合法
- }
- }
- }
java代码:
- <bean id="userModelValidator"
- class="cn.javass.chapter4.web.controller.support.validator.UserModelValidator"/>
- <bean name="/validator"
- class="cn.javass.chapter4.web.controller.RegisterSimpleFormController">
- <property name="formView" value="registerAndValidator"/>
- <property name="successView" value="redirect:/success"/>
- <property name="validator" ref="userModelValidator"/>
- </bean>
java代码:
- username.not.empty=用户名不能为空
- username.not.illegal=用户名错误,必须以字母开头,只能出现字母、数字、下划线,并且长度在5-20之间
- username.forbidden=用户名中包含非法关键词【{0}】
- password.not.illegal=密码长度必须在5-20之间
java代码:
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
- <form:form commandName="user">
- <form:errors path="*" cssStyle="color:red"></form:errors><br/>
- username:<form:input path="username"/>
- <form:errors path="username" cssStyle="color:red"></form:errors>
- <br/>
- password:<form:password path="password"/>
- <form:errors path="password" cssStyle="color:red"></form:errors>
- <br/>
- <input type="submit" value="注册"/>
- </form:form>
java代码:
- BindException errors = new BindException(user, getCommandName(user));
- //如果用户名为空
- if(!StringUtils.hasLength(user.getUsername())) {
- errors.rejectValue("username", "username.not.empty");
- }
- if(errors.hasErrors()) {
- return new ModelAndView(getCreateView()).addAllObjects(errors.getModel());
- }