本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云
数据校验在web系统中非常常见,也非常常用。本文将借助SpringMVC的编程式验证器来学习一下Validator。
数据不合法
- 比如用户名长度必须在5-20之间,而且必须以字母开头,可包含字母、数字、下划线;
- 比如注册用户时 用户名已经存在或邮箱已经存在等;
- 比如去一些论坛经常会发现,您发的帖子中包含×××屏蔽关键字等。
还有很多数据不合法的场景,在此就不罗列了,对于数据不合法,Spring Web MVC提供了两种验证方式:
- 编程式验证器验证
- 声明式验证
编程式验证器
package org.springframework.validation; public interface Validator { boolean supports(Class<?> clazz); void validate(Object target, Errors errors); }
- Validator接口:验证器,编程实现数据验证的接口;
- supports方法:当前验证器是否支持指定的clazz验证,如果支持返回true即可;
- validate方法:验证的具体方法,target参数表示要验证的目标对象(如命令对象),errors表示验证出错后存放错误信息的错误对象。
验证器实现
package com.xttblog.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", "密码不合法");//密码不合法 } } }
- supports方法:表示只对UserModel类型的对象验证;
- validate方法:数据验证的具体方法,有如下几个验证:
用户名不合法(长度5-20,以字母开头,随后可以是字母、数字、下划线)
USERNAME_PATTERN.matcher(user.getUsername()).matches() //使用正则表达式验证 errors.rejectValue("username", "username.not.illegal");//验证失败为username字段添加错误码
屏蔽关键词:即用户名中含有不合法的数据(如admin)
user.getUsername().contains(forbiddenWord) //用contains来判断我们的用户名中是否含有非法关键词 errors.rejectValue("username", "username.forbidden", new Object[]{forbiddenWord}, "您的用户名包含非法关键词"); //验证失败为username字段添加错误码(参数为当前屏蔽关键词)(默认消息为"您的用户名包含非法关键词")
密码不合法,例如密码不能低于6位数等。
ValidationUtils
ValidationUtils.rejectIfEmpty(errors, "username", "username.not.empty"); 表示如果目标对象的username属性数据为空,则添加它的错误码; 内部通过(value == null || !StringUtils.hasLength(value.toString()))实现判断value是否为空,从而简化代码。
spring配置文件chapter4-servlet.xml
<bean id="userModelValidator" class="com.xttblog.chapter4.web.controller.support.validator.UserModelValidator"/> <bean name="/validator" class="com.xttblog.chapter4.web.controller.RegisterSimpleFormController"> <property name="formView" value="registerAndValidator"/> <property name="successView" value="redirect:/success"/> <property name="validator" ref="userModelValidator"/> </bean>
错误码配置(messages.properties),需要执行NativeToAscii
username.not.empty=用户名不能为空 username.not.illegal=用户名错误,必须以字母开头,只能出现字母、数字、下划线,并且长度在5-20之间 username.forbidden=用户名中包含非法关键词【{0}】 password.not.illegal=密码长度必须在5-20之间
视图页面(/WEB-INF/jsp/registerAndValidator.jsp)
<%@ 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>
form:errors path="username":表示只显示username字段的错误信息;
输入地址:http://localhost:9080/springmvc-chapter4/validator进行测试。
当我们输入错误的数据后,会报错(form:errors path="*"显示所有错误信息,而form:errors path="username"只显示该字段相关的)。
如MultiActionController控制器相关方法没有提供给我们errors对象(Errors),我们应该怎么进行错误处理呢?
此处给大家一个思路,errors本质就是一个Errors接口实现,而且在页面要读取相关的错误对象,该错误对象应该存放在模型对象里边,因此我们可以自己创建个errors对象并将其添加到模型对象中即可。
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()); }
- new BindException(user, getCommandName(user)):使用当前的命令对象,和命令对象的名字创建了一个BindException作为errors;
- StringUtils.hasLength(user.getUsername()):如果用户名为空就是用errors.rejectValue("username", "username.not.empty");注入错误码;
- errors.hasErrors():表示如果有错误就返回到新增页面并显示错误消息;
- ModelAndView(getCreateView()).addAllObjects(errors.getModel()):此处一定把errors对象的模型数据放在当前的ModelAndView中,作为当前请求的模型数据返回。
在浏览器地址栏输入:http://localhost:9080/springmvc-chapter4/userAndValidator/create 到新增页面
用户名什么都不输入,提交后又返回到新增页面 而且显示了错误消息说明我们的想法是正确的。本文示例源码下载链接:http://pan.baidu.com/s/1bpvohZp 密码:wgde
最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!
本文原文出处:业余草: » SpringMVC编程式验证器Validator