注解方式校验vo

目录结构

1、注解类

package com.annotation.validation.annotation;

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldValidate {

    /**
     * 字段属性是否为空
     * @return
     */
    public boolean isEmpty() default false;

    /**
     * 字段长度
     * @return
     */
    public int max() default 0;

    /**
     * 当字段为条件必填时,需要配合conKey和conVal一起,例如conKey="idKind",conVal="90"
     * @return
     */
    public String conKey() default "";

    public String conVal() default "";
}
package com.annotation.validation.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BigDecimalValidate {
    /**
     * 字段长度
     * @return
     */
    public int length() default 10;

    /**
     * 保留小数位
     * @return
     */
    public int scale() default 2;

    /**
     * 是否可以是负数
     * @return
     */
    public boolean isNegative() default false;
}
package com.annotation.validation.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DateValidate {

    /**
     * 日期格式
     * @return
     */
    public String format() default "yyyy-MM-dd";
}
package com.annotation.validation.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ObjectValidate {

    public Class<?> className();
}

2、校验工具类

package com.annotation.validation.utils;

import com.annotation.validation.annotation.BigDecimalValidate;
import com.annotation.validation.annotation.DateValidate;
import com.annotation.validation.annotation.FieldValidate;
import com.annotation.validation.annotation.ObjectValidate;
import com.annotation.validation.vo.ValidateVo;
import org.apache.commons.lang.StringUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

public class ValidateUtil {

    private static Map<String ,Object> REFLECT_CACHE = new ConcurrentHashMap<>();

    public static Map<String,Object> validateJson(Object bean,String prefixMsg){
        Map <String,Object> result = new HashMap();
        result.put("message","校验通过");
        result.put("result",true);
        Class<?> cls = bean.getClass();
        StringBuffer errorMsgBuffer = new StringBuffer(prefixMsg);

        boolean flag = true;
        //检测field是否存在
        String key = null;
        try{
            Field [] fields = null;
            key = cls.getName();
            if(REFLECT_CACHE.containsKey(key)){
                fields = (Field[])REFLECT_CACHE.get(key);
            }else{
                fields = cls.getDeclaredFields();
                REFLECT_CACHE.put(cls.getName(),fields);
            }
            for (Field field : fields) {
                field.setAccessible(true);//反射时访问私有变量
                Object value = field.get(bean);//获取字段值
                Annotation[] annoArr = null;//获取字段上的注解集合
                key = String.format("%s_%s",cls.getName(),field.getName());
                if(REFLECT_CACHE.containsKey(key)){
                    annoArr = (Annotation[]) REFLECT_CACHE.get(key);
                }else{
                    annoArr = field.getAnnotations();
                    REFLECT_CACHE.put(key,annoArr);
                }
                for (Annotation annotation : annoArr) {
                    Class<? extends Annotation> aClass = annotation.annotationType();//获取注解类型
                    Method [] methodArr = null;
                    key = String.format("%s_%s_%s",cls.getName(),field.getName(),aClass.getName());
                    if(REFLECT_CACHE.containsKey(key)){
                        methodArr = (Method[]) REFLECT_CACHE.get(key);
                    }else{
                        methodArr = aClass.getDeclaredMethods();
                        REFLECT_CACHE.put(key,methodArr);
                    }
                    for (Method method : methodArr) {
                        String methodName = method.getName();//获取注解类中的方法名
                        if("message".equals(methodName)||"conVal".equals(methodName)){//过滤错误提示方法的调用
                            continue;
                        }
                        if("conKey".equals(methodName)){//当字段为必填时,做特殊校验
                            result.put("message","校验通过");
                            result.put("result",true);
                            FieldValidate ann = field.getAnnotation(FieldValidate.class);
                            if(StringUtils.isNotBlank(ann.conKey())&&StringUtils.isNotBlank(ann.conVal())){
                                Method m = null;
                                key = String.format("METHOD_%s_%s",cls.getName(),methodName);
                                if(REFLECT_CACHE.containsKey(key)){
                                    m = (Method) REFLECT_CACHE.get(key);
                                }else{
                                    m = cls.getMethod(getMethodName(ann.conKey()));
                                    REFLECT_CACHE.put(key,m);
                                }
                                String valStr = (String)m.invoke(bean);
                                String tmpr = ("," + ann.conVal() + ",");
                                int temp = ("," + ann.conVal() + ",").indexOf("," + valStr + ",");
                                if((StringUtils.isNotBlank(valStr)) && ("," + ann.conVal() + ",").indexOf("," + valStr + ",") >= 0) {
                                    if(StringUtils.isBlank((String)value)) {
                                        flag = false;
                                        errorMsgBuffer.append(String.format("当字段[%s]符合条件[%s]时,[%s]字段不能为空",ann.conKey(),ann.conVal(),field.getName()) + ";");
                                    }
                                }
                            }
                            continue;
                        }
                        // 初始化注解验证的方法处理类 (我的处理方法加载本类中)
                        Object obj = ValidateUtil.class.newInstance();
                        // 获取方法
                        try {
                            // 根据方法名获取该方法
                            Method m =  null;
                            if(REFLECT_CACHE.containsKey(String.format("METHOD_%s", methodName))) {
                                m = (Method) REFLECT_CACHE.get(String.format("METHOD_%s", methodName));
                            } else {
                                m = obj.getClass().getDeclaredMethod(methodName, Object.class, Field.class);
                                REFLECT_CACHE.put(String.format("METHOD_%s", methodName), m);
                            }
                            // 调用该方法
                            result = (Map<String, Object>)m.invoke(obj, value, field);
                            /* 验证结果 拼接字符串 */
                            if(result.get("result").equals(false)) {
                                errorMsgBuffer.append(result.get("message"));
                                if(! (annotation instanceof ObjectValidate)) {
                                    errorMsgBuffer.append(";");
                                }
                                flag = false;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            result.put("result", false);
                            result.put("message", String.format("%s执行数据校验时异常1:%s", prefixMsg, e));
                            return result;
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            result.put("result", false);
            result.put("message", String.format("%s执行数据校验时异常2:%s", prefixMsg, e));
            return result;
        }
        result.put("result", flag);
        result.put("message", flag ? "校验成功" : errorMsgBuffer.toString());
        return result;
    }

    public static String getMethodName(String fieldName){
        byte[] bytes = fieldName.getBytes();
        bytes[0] = (byte)((char)bytes[0] - 'a' + 'A');
        return "get".concat(new String(bytes));
    }
    /**
     * 验证最大值
     *
     * @author zhy
     * @param value 参数值
     * @param field 字段
     * @return
     */
    public Map<String, Object> max(Object value, Field field) {
        Map<String, Object> validateResult = new HashMap<String, Object>();
        FieldValidate annotation = field.getAnnotation(FieldValidate.class);
        int len = 0;
        if(value instanceof String) {
            len = value.toString().length();
        }
        if(value != null && !value.equals("") && annotation.max() > 0 &&  len > annotation.max()) {
            validateResult.put("message", String.format("[%s]]字段长度过长, 长度最大限制为%s", field.getName(), annotation.max()));
            validateResult.put("result", false);
        } else {
            validateResult.put("message", "验证通过");
            validateResult.put("result", true);
        }

        return validateResult;
    }

    /**
     * 验证是否空值
     *
     * @author zhy
     * @param value 参数值
     * @param field 字段
     * @return
     */
    public Map<String, Object> isEmpty(Object value, Field field) {
        Map<String, Object> validateResult = new HashMap<String, Object>();
        validateResult.put("message", "验证通过");
        validateResult.put("result", true);

        FieldValidate annotation = field.getAnnotation(FieldValidate.class);
        if(!annotation.isEmpty()) {
            if(value == null || value.equals("")) {
                validateResult.put("message", String.format("[%s]字段不能为空值", field.getName()));
                validateResult.put("result", false);
            }

            if(value != null && value instanceof List) {
                if(((List)value).size() == 0) {
                    validateResult.put("message", String.format("[%s]字段不能为空值", field.getName()));
                    validateResult.put("result", false);
                }
            }
        }

        return validateResult;
    }

    /**
     * 校验日期格式是否正确
     * @param value
     * @param field
     * @return
     */
    public Map<String, Object> format(Object value, Field field) {
        Map<String, Object> validateResult = new HashMap<String, Object>();
        validateResult.put("message", "验证通过");
        validateResult.put("result", true);

        DateValidate annotation = field.getAnnotation(DateValidate.class);
        if(StringUtils.isNotBlank((String)value)) {
            try {
                Date dateTime = convertStringToDate(annotation.format(), (String)value);
                String dateStr = getDateString(dateTime, annotation.format());
                if(!dateStr.equals((String)value)) {
                    validateResult.put("message", String.format("[%s]字段日期格式不正确, 日期格式为%s", field.getName(), annotation.format()));
                    validateResult.put("result", false);
                }
            } catch (Exception e) {
                validateResult.put("message", String.format("[%s]字段日期格式不正确, 日期格式为%s", field.getName(), annotation.format()));
                validateResult.put("result", false);
            }
        }

        return validateResult;
    }

    /**
     * 校验是否为Decimal规定的格式:校验长度
     * @param value
     * @param field
     * @return
     */
    public Map<String, Object> length(Object value, Field field) {
        Map<String, Object> validateResult = new HashMap<String, Object>();
        validateResult.put("message", "验证通过");
        validateResult.put("result", true);
        BigDecimalValidate annotation = field.getAnnotation(BigDecimalValidate.class);
        String strVal = (String)value;
        if(StringUtils.isNotBlank(strVal)) {
            boolean flag = Pattern.matches("^-?[0-9]+\\.?[0-9]*$", strVal);
            if(!flag) {
                validateResult.put("message", String.format("[%s]字段不符合金额规则", field.getName()));
                validateResult.put("result", false);
                return validateResult;
            }

            if(strVal.replace(".", "").replace("-", "").length() > annotation.length()) {
                validateResult.put("message", String.format("[%s]字段长度过长,最大长度为%s", field.getName(), annotation.length()));
                validateResult.put("result", false);
            }
        }

        return validateResult;
    }

    /**
     * 校验是否可以是负数
     * @param value
     * @param field
     * @return
     */
    public Map<String, Object> isNegative(Object value, Field field) {
        Map<String, Object> validateResult = new HashMap<String, Object>();
        validateResult.put("message", "验证通过");
        validateResult.put("result", true);
        BigDecimalValidate annotation = field.getAnnotation(BigDecimalValidate.class);
        String strVal = (String)value;
        if(StringUtils.isNotBlank(strVal) && !annotation.isNegative()) {
            boolean flag = Pattern.matches("^-?[0-9]+\\.?[0-9]*$", strVal);
            if(flag) {
                BigDecimal bigDecimal = new BigDecimal(strVal);
                if(bigDecimal.compareTo(new BigDecimal(0)) < 0) {
                    validateResult.put("message", String.format("[%s]字段不能为负值", field.getName()));
                    validateResult.put("result", false);
                }
            }
        }

        return validateResult;
    }
    /**
     * 校验是否为Decimal规定的格式:校验小数点位数
     * @param value
     * @param field
     * @return
     */
    public Map<String, Object> scale(Object value, Field field) {
        Map<String, Object> validateResult = new HashMap<String, Object>();
        validateResult.put("message", "验证通过");
        validateResult.put("result", true);
        BigDecimalValidate annotation = field.getAnnotation(BigDecimalValidate.class);
        String strVal = (String)value;
        if(StringUtils.isNotBlank(strVal)) {
            String[] strs = strVal.split("\\.");
            if((strs.length == 1 ? 0 : strs[1].length()) > annotation.scale()) {
                validateResult.put("message", String.format("[%s]字段小数点位数过长,最大长度为%s", field.getName(), annotation.scale()));
                validateResult.put("result", false);
            }
        }

        return validateResult;
    }

    /**
     * 对字段类型为对象或者List进行校验
     * @param value
     * @param field
     * @return
     */
    public Map<String, Object> className(Object value, Field field) {
        Map<String, Object> validateResult = new HashMap<String, Object>();
        if(value != null) {
            if(value instanceof ArrayList) {
                List<Object> list = (List<Object>) value;
                validateResult.put("message", "验证通过");
                validateResult.put("result", true);
                StringBuffer buffer = new StringBuffer();
                boolean flag = true;
                for(Object val : list) {
                    Map<String, Object> result = ValidateUtil.validateJson(val, "");
                    if(!result.get("result").equals(true)) {
                        ObjectValidate annotation = field.getAnnotation(ObjectValidate.class);
                        flag = false;
                        buffer.append(String.format("%s对象中的参数有误:{%s}", annotation.className().getSimpleName(),
                                result.get("message")));
                    }
                }

                validateResult.put("result", flag);
                validateResult.put("message", flag ? "验证通过" : buffer.toString());
            } else {
                Map<String, Object> result = ValidateUtil.validateJson(value, "");
                if(result.get("result").equals(true)) {
                    validateResult.put("message", "验证通过");
                    validateResult.put("result", true);
                } else {
                    ObjectValidate annotation = field.getAnnotation(ObjectValidate.class);
                    validateResult.put("result", false);
                    validateResult.put("message", String.format("%s对象中的参数有误:{%s}", annotation.className().getSimpleName(),
                            result.get("message")));
                }
            }
        } else {
            validateResult.put("message", "验证通过");
            validateResult.put("result", true);
        }

        return validateResult;
    }
    public static final Date convertStringToDate(String aMask, String strDate) throws ParseException {
        SimpleDateFormat df = null;
        Date date = null;
        df = new SimpleDateFormat(aMask);
        try {
            date = df.parse(strDate);
        } catch (ParseException pe) {
            throw new ParseException(pe.getMessage(), pe.getErrorOffset());
        }

        return date;
    }

    public static String getDateString(Date _date, String patternString) {
        String dateString = "";
        if (_date != null) {
            SimpleDateFormat formatter = new SimpleDateFormat(patternString);
            dateString = formatter.format(_date);
        }
        return dateString;
    }
}

3、测试方法

public static void main(String []args){
        ValidateVo vo = new ValidateVo();
        vo.setApplicationId("csy12132");
        vo.setLoanAmount("2.4444");
        vo.setLoanDate("2020-10-23");
        ValidateVo.InnerVo innerVo = new ValidateVo.InnerVo();
        innerVo.setApplicationId("大世界");
        List<ValidateVo.InnerVo>list = new ArrayList<>();
        list.add(innerVo);
        vo.setInnerList(list);
        Map<String, Object> validateMap = ValidateUtil.validateJson(vo,String.format("调用接口[%s]参数有误",vo));
        validateMap.forEach((key,value)->
                System.out.println("key:"+key+",value:"+value));
    }

4、输出

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值