步骤是:配置数据校验规则(多条)>>>>在控制器上添加校验注解>>>>使用拦截器拦截校验参数(获取注解,初始化校验规则(第一次),取出参数)
我的项目中使用的MVC框架为Jfinal框架,其他框架也适用只需要将拦截器部分修改即可
使用方式非常简单,使用方式:
1.在controller层加上
校验接口版本号
@Version(version=1,message="请升级到最新版本")
2.配置拦截器:br/>@Override
public void onInterceptorConfig(Interceptors interceptors) {
interceptors.add(new ValidatorInterceptor());
}
3.在不同的实体类上配置校验规则:br/>@VRules(rules={
@VRule(attrName = "mobilePhone", message="手机号码有误", groups = { VGroup.save,VGroup.excutor }, types = { VType.mobilePhone } ),
@VRule(attrName = "password", message="密码最少为6位字符", groups = { VGroup.save }, types = { VType.password } ),
@VRule(attrName = "verifyCode", message="验证码有误", groups = { VGroup.excutor }, types = { VType.number } ),
@VRule(attrName = "messageId", message="验证码标识有误", groups = { VGroup.excutor }, types = { VType.notnull } )
})
public class Register implements Serializable{}
具体实现
/**
-
- 数据验证规则
-
- @author wdm([email protected]) @date 2018年5月30日
- @version 1.0
*/
public interface IVRule {
/**- 校验规则
*/
public static final Map<String,List<ValidatorRule>> BEAN_VALIDATOT_RULE=new HashMap<String,List<ValidatorRule>>();
/** - 是否初始化校验规则
*/
public static final Map<String,Boolean> IS_INIT_VALIDATOT_RULE=new HashMap<String,Boolean>();
}
/**<pre>
- 校验规则
-
- 用于controller层需要验证数据较多时的验证
- 默认VGroup=VGroup.excutor
- 默认VRenderType=VRenderType.json
-
- </pre>
- @author wdm([email protected]) @date 2018年5月30日
- @version 1.0br/>*/
@Documented
@Target(ElementType.METHOD)br/>@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Validator {
VGroup group() default VGroup.excutor;
Class<?> bean();
String beanName() default "";
String uri() default "";
VRenderType render() default VRenderType.json;
}
/** -
- 用于controller层验证版本号
-
- @author wdm([email protected]) @date 2018年5月30日
- @version 1.0br/>*/
@Documented
@Target(ElementType.METHOD)br/>@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Version {
String message();
int version();
}
package com.www.mall.common.validator;
public enum VRenderType {
json,redirect,render
}
/**
-
- 配置一条校验规则
-
- @author wdm([email protected]) @date 2018年7月31日
- @version 1.0br/>*/
@Documented
@Target(ElementType.METHOD)br/>@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface VRule {
VGroup[] groups() default {VGroup.excutor};
VType[] types();
String attrName();
String message() default "参数错误";
}
/** -
- 校验规则
-
- @author wdm([email protected]) @date 2018年7月31日
- @version 1.0br/>*/
@Documented
@Target(ElementType.TYPE)br/>@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface VRules {
VRule[] rules();
}
/** -
- 验证数据类型
-
- @author wdm([email protected]) @date 2018年5月30日
-
@version 1.0
*/
public enum VType {
/非空验证/
notnull,
/非空时验证电子邮箱格式,空表示通过/
ne_email,
/非空时验证×××格式,空表示通过/
ne_idcard,/验证电子邮箱格式/
email,
/验证×××格式/
idcard,
/验证日期格式/
date,
/手机号验证/
mobilePhone,
/密码验证/
password,
/数字验证/
number
}
/** -
- 验证数据规则
-
- @author wdm([email protected]) @date 2018年5月30日
-
@version 1.0
*/
public class ValidatorRule {private List<VGroup> vGroups;
private List<VType> vTypes;
private String validatorField;
private String message;/**
- 构建一个数据验证规则
- @param validatorField
- @param message
- @param vGroups
- @param vTypes
- @return
*/
public static ValidatorRule bulid(String validatorField,String message,List<VGroup> vGroups,List<VType> vTypes){
return new ValidatorRule(vGroups,vTypes,validatorField,message);
}
/**
- 都需要验证的数据
- 如:save和update操作时都需要验证这个参数
- @param validatorGroups
- @return
*/
public static List<VGroup> group(VGroup... validatorGroups){
List<VGroup> list=new ArrayList<VGroup>();
for (int i = 0; i < validatorGroups.length; i++) {
list.add(validatorGroups[i]);
}
return list;
}
/**
- 数据的验证类型
- @param validatorTypes
- @return
*/
public static List<VType> type(VType... validatorTypes){
List<VType> list=new ArrayList<VType>();
for (int i = 0; i < validatorTypes.length; i++) {
list.add(validatorTypes[i]);
}
return list;
}
private ValidatorRule(){}
private ValidatorRule(List<VGroup> vGroups, List<VType> vTypes, String validatorField,
String message) {
super();
this.vGroups = vGroups;
this.vTypes = vTypes;
this.validatorField = validatorField;
this.message = message;
}public List<VGroup> getValidatorGroups() {
return vGroups;
}
public void setValidatorGroups(List<VGroup> vGroups) {
this.vGroups = vGroups;
}
public List<VType> getValidatorTypes() {
return vTypes;
}
public void setValidatorTypes(List<VType> vTypes) {
this.vTypes = vTypes;
}
public String getValidatorField() {
return validatorField;
}
public void setValidatorField(String validatorField) {
this.validatorField = validatorField;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
数据校验拦截器
/**
-
- 参数验证拦截器
-
- @author wdm([email protected]) @date 2018年5月31日
-
@version 1.0
*/
public class ValidatorInterceptor implements Interceptor {@Override
public void intercept(Invocation inv) {
Version version=inv.getMethod().getAnnotation(Version.class);
if(version!=null && !verifyVersion(inv, version)){
return;
}Validator validator = inv.getMethod().getAnnotation(Validator.class); if (validator != null && !validate(inv, validator)) { return; } inv.invoke();
}
private boolean verifyVersion(Invocation inv, Version version) {
int vers=version.version();
String message=StringUtils.isBlank(version.message())?"该功能已升级,如要继续使用请升级app到最新版本":version.message();
Controller controller=inv.getController();if(vers>-1){ int verifyVersion = -1; String versionStr= controller.getHeader("version");//验证版本号 if(versionStr!=null){ try { verifyVersion=Integer.valueOf(versionStr); } catch (Exception e) { //版本信息错误 必须是int类型数字 e.printStackTrace(); } } if(verifyVersion<vers){ renderError( controller,VRenderType.json, "" ,RC.VERSION_FAIL,message); return false; } } return true;
}
/**- 验证JSON格式的数据
- @param inv
- @param validator
-
@return
*/
private boolean validate(Invocation inv, Validator validator) {
VRenderType vRenderType=validator.render();
VGroup group = validator.group();
Controller controller=inv.getController();
Class<?> clazz=validator.bean();
String validatorBeanName=clazz.getName();//初始化校验规则
initValidatorRule(validatorBeanName, clazz);
List<ValidatorRule> list=IVRule.BEAN_VALIDATOT_RULE.get(validatorBeanName);if (list==null) {//没有验证规则
return true;
}JSONObject jsonObject= json(controller.getPara("param"),controller.getHeader("ploy"));
String beanName=validator.beanName()+".";
for (int i = 0; i < list.size(); i++) {//循环每一条数据规则
ValidatorRule validatorRule=list.get(i);
List<VGroup> groups = validatorRule.getValidatorGroups();
if(groups.contains(group)){//包含分组-需要验证该组数据
String field=beanName+validatorRule.getValidatorField();
String message=validatorRule.getMessage();
List<VType> validatorRules=validatorRule.getValidatorTypes();
for (int j = 0; j < validatorRules.size(); j++) {
VType vType=validatorRules.get(j);String value =jsonObject==null ?null : jsonObject.getString(field);//controller.getPara(field); if(!validate(vType,value)){ renderError(controller,vRenderType, validator.uri(),RC.PARAM_FAIL,message); return false; } } }
}
return true;
}
/**
- 初始化验证规则
- @param isInit
- @param bean
*/
private void initValidatorRule(String validatorBeanName,Class<?> clazz) {
Boolean isInit=IVRule.IS_INIT_VALIDATOT_RULE.get(validatorBeanName);
if(isInit!=null && isInit){//是否已经初始化
return;
}
VRules vRules=clazz.getAnnotation(VRules.class);
if(vRules!=null){
VRule[] rules=vRules.rules();
if(rules.length>0){
List<ValidatorRule> validatorRules=new ArrayList<ValidatorRule>();
for (int i = 0; i < rules.length; i++) {
VRule vRule=rules[i];
String attrName=vRule.attrName();
String message=vRule.message();
VGroup[] validatorGroups=vRule.groups();
VType[] validatorTypes=vRule.types();
validatorRules.add(ValidatorRule.bulid( attrName, message,ValidatorRule.group(validatorGroups), ValidatorRule.type(validatorTypes)));
}
IVRule.BEAN_VALIDATOT_RULE.put(validatorBeanName, validatorRules);
}
}
IVRule.IS_INIT_VALIDATOT_RULE.put(validatorBeanName,true);
}
protected JSONObject json(String json,String ploy){
if(Ploy.ENCRYPT.equals(ploy)){//参数解密
json=ParamUtil.decryptParam(json);
if(json==null){
return null;
}
}
return JSON.parseObject(json);
}
/**
- 有需要再追加
- @param vType
- @param value
-
@return
*/
private boolean validate(VType vType, String value) {
if(vType==VType.notnull){
return com.xiaoleilu.hutool.lang.Validator.isNotEmpty(value);
}else if(vType==VType.email){
return com.xiaoleilu.hutool.lang.Validator.isEmail(value);
}else if(vType==VType.idcard){
return IdcardUtil.isvalidCard18(value);
}else if(vType==VType.ne_email){
if( com.xiaoleilu.hutool.lang.Validator.isNotEmpty(value)){
return true;
}
return RegexUtils.checkEmail(value);
}else if(vType==VType.ne_idcard){
if( com.xiaoleilu.hutool.lang.Validator.isNotEmpty(value)){
return true;
}
return IdcardUtil.isvalidCard18(value);
}else if(vType==VType.mobilePhone){
return com.xiaoleilu.hutool.lang.Validator.isMobile(value) && value.length()==11;
}else if(vType==VType.password){
return value!=null && value.length()>5;
}else if(vType==VType.number){
return com.xiaoleilu.hutool.lang.Validator.isNumber(value);
}return true;
}
private void renderError(Controller controller,VRenderType vRenderType, String redirect,RC result,String message) {
if (controller instanceof JbootController) {
if(vRenderType==VRenderType.json){
controller.renderJson(Ret.paramFail(message));
}else if(vRenderType==VRenderType.redirect){
if(StringUtils.isNotBlank(redirect)){
controller.redirect(redirect);
}
// ((JbootController) controller).setFlashAttr("message", message);
// ((JbootController) controller).setFlashAttr("result", result);
controller.renderJson(Ret.result(result.getState(), message));
}else if(vRenderType==VRenderType.render){
controller.keepPara();
if(StringUtils.isNotBlank(redirect)){
controller.render(redirect);
}
// ((JbootController) controller).setFlashAttr("message", message);
// ((JbootController) controller).setFlashAttr("result", result);
controller.renderJson(Ret.result(result.getState(), message));
}else{
if(StringUtils.isNotBlank(redirect)){
controller.redirect(redirect);
}
// ((JbootController) controller).setFlashAttr("message", message);
// ((JbootController) controller).setFlashAttr("result", result);
controller.renderJson(Ret.result(result.getState(), message));
}
}
}
}