版本:
Javax的validation-api-2.0.1.Final.jar用来进行数据校验(不推荐使用Hibernate-validator);
Hibernate-validator-6.0.11.Final.jar用来配合SpringMVC进行国际化配置
1、springMVC-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- <context:annotation-config/>被component-scan包括 -->
<!-- 启动spring MVC 注解 -->
<!-- 设置使用注解的类所在的jar包以及sub package,controller类 -->
<context:component-scan base-package="main.java.com.smart.*" use-default-filters="true">
<!--
<context:include-filter type="annotation" expression=""/>
<context:exclude-filter type="annotation" expression=""/>
-->
</context:component-scan>
<!-- 完成请求和注解POJO的映射 -->
<!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> -->
<!-- 不处理静态资源文件 -->
<!-- <mvc:default-servlet-handler/> -->
<!-- 如果使用了注释后必须配置设置 -->
<mvc:annotation-driven validator="validator"/>
<!-- start:国际化配置 -->
<!-- 读取国际化资源文件 == 资源文件在包里面,路径写全包名-->
<!-- 当国际化配置文件在WEB-INF下时使用org.springframework.context.support.ResourceBundleMessageSource -->
<!--定义校验器数据源bean-->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" value="classpath:resources/i18n/messages" />
<property name="cacheSeconds" value="3600" />
</bean>
<!-- 校验器 -->
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!--指定校验器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<!--引入校验器校验的数据源,注意ref和value的区别,前者引入一个object,后者引入string-->
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<!-- end:国际化配置 -->
</beans>
2、resources/i18n下的文件
这里有两个文件作为测试用,messages.properties和messages_zh_CN.properties
前者:
NotEmpty.user.nickname=User nicknames cannot be empty
Pattern.user.password=Passwords can only be a combination of 6 - to 30-bit letters, Numbers, and underscores
Pattern.user.phone=The phone number can only be 11 digits
Between.user.age=The age range is 9 to 100
Email.user.email=The E-mail format is incorrect
后者
NotEmpty.user.nickname=\u7528\u6237\u6635\u79F0\u4E0D\u80FD\u4E3A\u7A7A
Pattern.user.password=\u5BC6\u7801\u53EA\u80FD6\u523030\u4F4D\u7684\u5B57\u6BCD\u6570\u5B57\u548C\u4E0B\u5212\u7EBF\u7EC4\u5408
Pattern.user.phone=\u624B\u673A\u53F7\u7801\u53EA\u80FD\u4E3A11\u4F4D\u6570\u5B57\u7EC4\u5408
Between.user.age=\u5E74\u9F84\u53EA\u80FD\u57289\u5230100\u5C81\u533A\u95F4
Email.user.email=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u90AE\u4EF6\u5730\u5740
3、领域对象中的User.java
package main.java.com.smart.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import main.java.com.smart.annotation.Between;
/**
*
* @class main.java.com.smart.domain.User
* @author ljj
* @date 2018年6月11日
* @notes 用户模型,
* tip:使用JSR-303验证框架注解为模型对象指定验证信息
*/
@SuppressWarnings("serial")
public class User implements Serializable {
/*
* head_addr:用户头像地址
* nickname:用户昵称
* user_id:用户ID,身份标识1
* password:用户密码
* phone:手机号码:身份标识2
* sex:用户性别
* region:用户所在地区
* mailbox:邮箱
* profession:职业
* academy:学院
* signature:个性签名
* last_ip:最后一次登录的IP
* last_visit:最后一次访问的时间
* status:用户登录状态,1为在线,0为离线
*/
private String head_addr;
@NotEmpty(message = "{NotEmpty.user.nickname}")
private String nickname;
private Integer user_id;
@Pattern(regexp = "[0-9a-zA-Z_]{6,30}",message = "{Pattern.user.password}")
private String password;
@Pattern(regexp = "[0-9]{11}",message = "{Pattern.user.phone}")
private String phone;
@NotNull
@Between(max = 100, min = 9,message = "{Between.user.age}")//自定义注解类
private Integer age;
private String sex;
private String region;
@Email(message = "{Email.user.email}")
private String mailbox;
private String profession;
private String academy;
private String signature;
private String last_ip;
private Date last_visit;
private int status;
//以上为mysql数据库的用户信息,以下为hbase数据库的用户信息
/*
* followers:当前用户关注其他用户的列表
* fans:粉丝列表
*/
List<User> followers = new ArrayList<User>();
List<User> fans = new ArrayList<User>();
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getAcademy() {
return academy;
}
public void setAcademy(String academy) {
this.academy = academy;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public List<User> getFollowers() {
return followers;
}
public void setFollowers(List<User> followers) {
this.followers = followers;
}
public List<User> getFans() {
return fans;
}
public void setFans(List<User> fans) {
this.fans = fans;
}
public String getHead_addr() {
return head_addr;
}
public void setHead_addr(String head_addr) {
this.head_addr = head_addr;
}
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getMailbox() {
return mailbox;
}
public void setMailbox(String mailbox) {
this.mailbox = mailbox;
}
public String getLast_ip() {
return last_ip;
}
public void setLast_ip(String last_ip) {
this.last_ip = last_ip;
}
public Date getLast_visit() {
return last_visit;
}
public void setLast_visit(Date last_visit) {
this.last_visit = last_visit;
}
@Override
public String toString() {
return "User [head_addr=" + head_addr + ", nickname=" + nickname + ", user_id=" + user_id + ", password="
+ password + ", phone=" + phone + ", sex=" + sex + ", region=" + region + ", mailbox=" + mailbox
+ ", profession=" + profession + ", academy=" + academy + ", signature=" + signature + ", last_ip="
+ last_ip + ", last_visit=" + last_visit + ", status=" + status + ", followers=" + followers + ", fans="
+ fans + "]";
}
}
4、自定义校验类
Between.java,定义校验类接口类,可参考其它内部校验方法做出修改形成个人定义的校验类接口
package main.java.com.smart.annotation;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Documented
@Constraint(validatedBy = {BetweenValidator.class})//约束
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface Between {
String message() default "{Between.user.age}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
int min();
int max();
}
BetweenValidator.java,定义校验规则实现类
package main.java.com.smart.annotation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 范围校验类
*
* @class main.java.com.smart.annotation.BetweenValidator
* @author ljj
* @date 2018年7月23日
* @notes
*
*/
public class BetweenValidator implements ConstraintValidator<Between, Integer> {
private int min;
private int max;
@Override
public void initialize(Between annotation) {
min = annotation.min();
max = annotation.max();
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
if(value == null) {
return false;
}
if(value >= min && value <= max){
return true;
}
return false;
}
}
5、UserController.java
package main.java.com.smart.web;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import main.java.com.smart.domain.User;
import main.java.com.smart.service.UserService;
@Controller
@RequestMapping("user")
public class UserController {
/**
* 用户注册页面
*
* @param user
* @return
*/
@RequestMapping("/register")
public String doRegisterPage(User user){
return "/WEB-INF/jsp/register.jsp";
}
/**
*
* @param user 通过@valid来开启校验,将校验的错误结果集返回奥result
* @param result
* @param map
* @return
*/
@RequestMapping(value = "/doRegister",method = RequestMethod.POST)
public String doRegister(@Valid User user, BindingResult result, ModelMap map){
String confirmpwd = request.getParameter("confirmpwd");
//如果入参有问题,返回注册页面
if(result.hasErrors()){
List<FieldError> errorList = result.getFieldErrors();
for(FieldError error : errorList){
System.out.println(error.getField() + "*" +error.getDefaultMessage());
map.put("ERR_"+error.getField(), error.getDefaultMessage());
}
if(!user.getPassword().equals(confirmpwd)){
map.put("ERR_confirmpwd", "两次输入密码不一致");
}
return "/WEB-INF/jsp/register.jsp";
}
if(!user.getPassword().equals(confirmpwd)){
map.put("ERR_confirmpwd", "两次输入密码不一致");
return "/WEB-INF/jsp/register.jsp";
}
//--此处注册逻辑代码
return "/WEB-INF/jsp/registersuccess.jsp";
}
}
5、register.jsp文件示例
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户注册</title>
</head>
<body>
<div style="magin:0 auto; padding-top:100px;" align="center">
<form action="user/doRegister.html" method="post">
<p>
<span>手机号码:</span><input type="text" name="phone"><span>${ERR_phone}</span>
</p>
<p>
<span>密 码:</span><input type="password" name="password"><span>${ERR_password}</span>
</p>
<p>
<span>确认密 码:</span><input type="password" name="confirmpwd"><span>${ERR_confirmpwd}</span>
</p>
<p>
<span>昵 称:</span><input type="text" name="nickname"><span>${ERR_nickname}</span>
</p>
<p>
<span>邮 箱:</span><input type="text" name="mailbox"><span>${ERR_mailbox}</span>
</p>
<p>
<span>年 龄:</span><input type="text" name="age"><span>${ERR_age}</span>
</p>
<input type="submit" value="注册">
</form>
</div>
</body>
</html>
TIP:运行时看是否异常提示缺少其它jar包,将缺少的jar下载下来补救进去就木问题