参数校验注解处理&&AOP

此代码为实际工作中为减少多余而烦躁的参数校验所编写的注解工具,希望能帮助到同学们~

话不多说,直接上代码

注解类

package com.movetime.pms.common.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 ParamValidator {

    /**
     * 非空校验
     */
    String NOT_NULL = "NOT_NULL";

    /**
     * 手机号校验
     */
    String PHONE = "PHONE";

    /**
     * 身份证号校验
     */
    String IDENTITY = "IDENTITY";

    /**
     * 范围校验
     */
    String RANGE = "RANGE";

    /**
     * 校验类型,默认非空校验
     *
     * @return
     */
    String type() default NOT_NULL;

    /**
     * 属性名称
     *
     * @return
     */
    String fieldName() default "";

    /**
     * 校验不通过抛出的message
     *
     * @return
     */
    String message() default "";

    /**
     * 范围校验,传入合法范围
     *
     * @return
     */
    String[] range() default {};
}

AOP处理

package com.movetime.pms.common.aop;

import com.movetime.pms.common.annotation.ParamValidator;
import com.movetime.pms.common.exception.ServiceException;
import com.movetime.pms.common.exception.SystemException;
import com.movetime.pms.utils.ValidateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Aspect
@Component
public class ParamCheckAop {

    @Pointcut("execution(public * com.movetime.pms.web.service.*.*(..))")
    public void checkParam() {
    }

    @Before("checkParam()")
    public void doBefore(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            Field[] declaredFields = arg.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                ParamValidator paramValidator = field.getDeclaredAnnotation(ParamValidator.class);
                //如果没有设置当前注解 不用校验
                if (paramValidator != null) {
                    validate(arg, field, paramValidator);
                }
            }
        }
    }

    private static <T> void validate(T t, Field field, ParamValidator paramValidator) {
        try {
            Object o = field.get(t);
            switch (paramValidator.type()) {
                case ParamValidator.NOT_NULL:
                    checkNull(paramValidator, o);
                    break;
                case ParamValidator.PHONE:
                    checkPhone(paramValidator, o);
                    break;
                case ParamValidator.IDENTITY:
                    checkIdentity(paramValidator, o);
                    break;
                case ParamValidator.RANGE:
                    checkRange(paramValidator, o);
                    break;
                default:
            }
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            throw new SystemException();
        }
    }

    private static void checkNull(ParamValidator paramValidator, Object o) {
        if (o == null || StringUtils.isEmpty(o.toString())) {
            String fieldName = paramValidator.fieldName();
            String message = paramValidator.message();
            if (StringUtils.isNotEmpty(message)) {
                throw new ServiceException(message);
            }
            throw new ServiceException(fieldName + "不能为空");
        }
    }

    private static void checkPhone(ParamValidator paramValidator, Object o) {
        checkNull(paramValidator, o);
        if (!ValidateUtils.isMobile(o.toString())) {
            String message = paramValidator.message();
            if (StringUtils.isNotEmpty(message)) {
                throw new ServiceException(message);
            }
            throw new ServiceException("手机号不合法");
        }
    }

    private static void checkIdentity(ParamValidator paramValidator, Object o) {
        checkNull(paramValidator, o);
        if (!ValidateUtils.isLegalPattern(o.toString())) {
            String message = paramValidator.message();
            if (StringUtils.isNotEmpty(message)) {
                throw new ServiceException(message);
            }
            throw new ServiceException("身份证号不合法");
        }
    }

    private static void checkRange(ParamValidator paramValidator, Object o) {
        List list = (List) o;//传入的范围
        if (CollectionUtils.isEmpty(list)) {
            throw new ServiceException(paramValidator.fieldName() + "不能为空");
        }
        String[] range = paramValidator.range();
        List<String> rangeList = Arrays.asList(range);//定义的范围

        for (Object item : list) {
            if (!rangeList.contains(item.toString())) {
                throw new ServiceException(paramValidator.fieldName() + "存在非法的值: " + item);
            }
        }
    }
}

校验Utils类

package com.movetime.pms.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.util.TextUtils;

import java.util.regex.Pattern;
import java.util.stream.IntStream;


public class ValidateUtils {
    private static final String REGEX_MOBILE = "((\\+86|0086)?\\s*)((134[0-8]\\d{7})|(((13([0-3]|[5-9]))|(14[5-9])|15([0-3]|[5-9])|(16(2|[5-7]))|17([0-3]|[5-8])|18[0-9]|19(1|[8-9]))\\d{8})|(14(0|1|4)0\\d{7})|(1740([0-5]|[6-9]|[10-12])\\d{7}))";

    /**
     * 身份证校验码
     */
    private static final int[] COEFFICIENT_ARRAY = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

    /**
     * 身份证号的尾数规则
     */
    private static final String[] IDENTITY_MANTISSA = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};

    private static final String IDENTITY_PATTERN = "^[0-9]{17}[0-9Xx]$";

    /**
     * 判断是否是手机号
     *
     * @param tel 手机号
     * @return boolean true:是  false:否
     */
    public static boolean isMobile(String tel) {
        if (StringUtils.isEmpty(tel)) {
            return false;
        }
        return Pattern.matches(REGEX_MOBILE, tel);
    }

    /**
     * 身份证号校验
     *
     * @param identity
     * @return
     */
    public static boolean isLegalPattern(String identity) {
        if (identity == null) {
            return false;
        }

        if (identity.length() != 18) {
            return false;
        }

        if (!identity.matches(IDENTITY_PATTERN)) {
            return false;
        }

        char[] chars = identity.toCharArray();
        long sum = IntStream.range(0, 17).map(index -> {
            char ch = chars[index];
            int digit = Character.digit(ch, 10);
            int coefficient = COEFFICIENT_ARRAY[index];
            return digit * coefficient;
        }).summaryStatistics().getSum();

        // 计算出的尾数索引
        int mantissaIndex = (int) (sum % 11);
        String mantissa = IDENTITY_MANTISSA[mantissaIndex];

        String lastChar = identity.substring(17);
        if (lastChar.equalsIgnoreCase(mantissa)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 手机号脱敏
     *
     * @param mobile
     * @return
     */
    public static String mobileEncrypt(String mobile) {
        int num = 11;
        if (TextUtils.isEmpty(mobile) || (mobile.length() != num)) {
            return mobile;
        }
        return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    /**
     * 身份证号脱敏
     *
     * @param id
     * @return
     */
    public static String idEncrypt(String id) {
        int num = 8;
        if (TextUtils.isEmpty(id) || (id.length() < num)) {
            return id;
        }
        return id.replaceAll("(?<=\\w{3})\\w(?=\\w{4})", "*");
    }
}

测试类

package com.movetime.pms.model.req;

import com.movetime.pms.common.annotation.ParamValidator;
import lombok.Data;

@Data
public class User{
    /**
     * 姓名
     */
    @ParamValidator(fieldName = "姓名")
    private String name;
    /**
     * 手机号
     */
    @ParamValidator(fieldName = "手机号", type = ParamValidator.PHONE)
    private String phone;
    /**
     * 性别 1男 2女
     */
    @ParamValidator(fieldName = "性别")
    private Integer gender;
    /**
     * 生日
     */
    private String birthday;
    /**
     * 照片
     */
    private String photo;
    /**
     * 身份证号
     */
    @ParamValidator(fieldName = "手机号", type = ParamValidator.IDENTITY)
    private String idNum;
}

转载请标明出处…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值