自定义检验注解_多注解自定义参数校验
好久直接更新了单个注解参数校验以后。偷懒了好久,今天就把多个注解自定义的参数校验写了一下,思路是一样的,只是一个注解包含的字段把它分解成了多个注解,类似于java-valid自带的不同功能的校验注解一般,自带的主要适用于不为空,数字型范围之类的校验,对于该属性包含几个值,集合元素个数的限制等都要自定义实现。下面我们这几肝一下:(打工人的觉悟,肝就完了)
我把原先的注解分成了四类
@Checked // 主要用来标记方法或者类是否是校验的
@CheckLength// 校验长度的,集合大小的
@CheckNull// 检验是否为空,去掉前后空格后是否为空
@CheckValues//校验参数值范围的
这几个注解的代码我就不贴上来的,去码云上面拉取就好了哦。
主要看使用注解校验的工具类:
package com.blog.annotation.two;import java.lang.reflect.Field;import java.lang.reflect.Type;import java.util.*;/** * @author 哲思小辉 * @version 1.0.0 * @ClassName CheckNullUtil.java * @Description 多个注解校验工具类 * @Param * @createTime 2020年07月26日 15:32:00 */public final class CheckNullUtil { private static final String ILLEGAL_STR = "%s值非法"; private static final String ILLEGAL_NULL_OR_EMPTY_STR = "%s为空"; /** * 长度类错误字符串 */ private static final String ILLEGAL_MIN_LENGTH_STR = "%s长度小于%s"; private static final String ILLEGAL_MAX_LENGTH_STR = "%s长度大于%s"; private static final String ILLEGAL_EQUAL_LENGTH_STR = "%s长度不等于%s"; /** * 个数类错误字符串 */ private static final String ILLEGAL_MIN_SIZE_STR = "%s元素个数小于%s"; private static final String ILLEGAL_MAX_SIZE_STR = "%s元素个数大于%s"; private static final String ILLEGAL_EQUAL_SIZE_STR = "%s元素个数不等于%s"; /** * 数值类错误字符串 */ private static final String ILLEGAL_MIN_VALUE_STR = "%s值小于%s"; private static final String ILLEGAL_MAX_VALUE_STR = "%s值大于%s"; private static final String ILLEGAL_EQUAL_VALUE_STR = "%s值不等于%s"; private static final String ILLEGAL_FIELD_MISSING_STR = "%s字段缺失"; private static final String ILLEGAL_FIELD_ERROR_STR = "%s中有参数为空"; private static final String GET_VALUE_FAIL_STR = "参数%s获取值失败"; private static final String REQUEST_OBJECT_NOT_NULL_STR = "请求对象为空"; /** * 基本数据类型set */ private static Setset; static { set = new HashSet<>(); set.add(int.class); set.add(short.class); set.add(byte.class); set.add(boolean.class); set.add(float.class); set.add(double.class); set.add(long.class); set.add(char.class); } /** * 校验是不是null,以及是不是为空 * * @param object * @param message * @throws Exception */ public static void checkNullAndEmpty(Object object, String message) throws Exception { checkNull(object, message); checkEmpty(object, message, null); } /** * 校验是不是为null * * @param message * @param object * @throws Exception */ public static void checkNull(Object object, String message) { message = message == null ? REQUEST_OBJECT_NOT_NULL_STR : message; checkBoolean(object == null, message); } /** * 校验元素为不为空 * * @param object * @param message * @throws Exception */ public static void checkEmpty(Object object, String message, Boolean isTrim) { // 先检测是否为null checkNull(object, message); boolean isOperator = false; if (object instanceof String) { // 字符串长度为0 String str = (String) object; str = isTrim ? str.trim() : str; isOperator = str.length() == 0; } else if (object instanceof Collection) { // 集合为空 isOperator = ((Collection) object).isEmpty(); } else if (object instanceof Map) { // Map为空 isOperator = ((Map) object).isEmpty(); } else if (object.getClass().isArray()) { // 数组个数为0 isOperator = ((Object[]) object).length == 0; } else if (object.getClass().isArray()) { // 数组长度为0 isOperator = ((Object[]) object).length == 0; } checkBoolean(isOperator, message); } /** * 校验Boolean值,如果为true就抛出异常 * * @param isOperator * @param message */ public static void checkBoolean(Boolean isOperator, String message) { if (isOperator != null && isOperator) { System.out.println("-------> " + message);// throw new IllegalArgumentException(message); } } /** * 检验Object * * @param req * @throws Exception */ public static void checkObject(Object req) throws Exception { checkObject(req, REQUEST_OBJECT_NOT_NULL_STR); } /** * 检验Object 自定义错误信息 * * @param req * @param message * @throws Exception */ public static void checkObject(Object req, String message) throws Exception { checkFields(req, message); } /** * 校验object对象 * * @param req * @throws Exception */ public static void checkFields(Object req, String message) throws Exception { checkNull(req, message); CheckNull checkNull = req.getClass().getAnnotation(CheckNull.class); if (checkNull != null && checkNull.notEmpty()) { checkEmpty(req, message, null); } Class> aClass = req.getClass(); Field[] fields = aClass.getDeclaredFields(); for (int i = 0; fields != null && i < fields.length; i++) { Field field = fields[i]; Class> type = field.getType(); field.setAccessible(true); String fieldName = field.getName(); Object object = null; try { object = field.get(req); } catch (IllegalAccessException e) { throw new Exception(String.format(GET_VALUE_FAIL_STR, fieldName)); } // 获取校验null和空的注解 CheckNull valueField = field.getAnnotation(CheckNull.class); CheckValues valuesCheckAn = field.getAnnotation(CheckValues.class); CheckLength lengthAn = field.getAnnotation(CheckLength.class); boolean isValuesAn = valuesCheckAn != null; boolean isLengthAn = lengthAn != null; // 如果没有任何自定义注解直接返回不校验 if (valueField == null && !isValuesAn && !isValuesAn) { continue; } // 如果注解不为空就校验 if (valueField != null) { String nullEmptyStr = String.format(ILLEGAL_NULL_OR_EMPTY_STR, fieldName); checkNull(valueField, nullEmptyStr); if (valueField.notEmpty()) { checkEmpty(object, nullEmptyStr, valueField.trim()); } } // 参数数据不为空再判断 if (object != null) { int equalLength = lengthAn == null ? 0 : lengthAn.equalLength(); int maxLength = lengthAn == null ? 0 : lengthAn.maxLength(); int minLength = lengthAn == null ? 0 : lengthAn.minLength(); String[] strings = valuesCheckAn == null ? null : valuesCheckAn.containValues(); Type superclass = type.getSuperclass(); // 获取接口 Class>[] interfaces = type.getInterfaces(); HashSet> classSet = new HashSet<>(Arrays.asList(interfaces)); if (String.class.equals(type)) { // String 类型处理 boolean trim = valueField == null ? false : valueField.trim(); String str = (String) object; if (trim) { str = str.trim(); } if (isLengthAn) { int length = str.length(); checkBoolean(minLength != 0 && length < minLength, String.format(ILLEGAL_MIN_LENGTH_STR, fieldName, minLength)); checkBoolean(maxLength != 0 && length > maxLength, String.format(ILLEGAL_MAX_LENGTH_STR, fieldName, maxLength)); checkBoolean(equalLength != 0 && length != equalLength, String.format(ILLEGAL_EQUAL_LENGTH_STR, fieldName, equalLength)); } if (isValuesAn && strings.length > 0) { Set valueSet = new HashSet<>(Arrays.asList(strings)); checkBoolean(!valueSet.contains(str), String.format(ILLEGAL_STR, fieldName)); } } else if (Number.class.equals(superclass) || set.contains(type)) { // 基本数据类型处理 if (isValuesAn) { String maxValue = valuesCheckAn.maxValue(); String minValue = valuesCheckAn.minValue(); String equalValue = valuesCheckAn.equalValue(); compareNumber(object, type, maxValue, minValue, equalValue, fieldName); if (strings.length > 0) { Set valueSet = new HashSet<>(Arrays.asList(strings)); checkBoolean(!valueSet.contains(String.valueOf(object)), String.format(ILLEGAL_STR, fieldName)); } } } else if (classSet.contains(Collection.class)) { // 集合类型处理 Collection collection = (Collection) object; int collectionSize = collection.size(); checkCollectionAndMapAndArray(collectionSize, equalLength, minLength, maxLength, fieldName, isLengthAn); if (collectionSize > 0) { for (Object o : collection) { checkObject(o, String.format(ILLEGAL_FIELD_ERROR_STR, fieldName)); } } } else if (classSet.contains(Map.class) || Map.class.equals(type)) { // Map类型处理 Map map = (Map) object; int mapSize = map.size(); checkCollectionAndMapAndArray(mapSize, equalLength, minLength, maxLength, fieldName, isLengthAn); for (int m = 0; isValuesAn && mapSize > 0 && m < strings.length; m++) { checkBoolean(!map.containsKey(strings[m]), String.format(ILLEGAL_FIELD_MISSING_STR, fieldName)); } } else if (type.isArray()) { // 数组的校验 Object[] arrays = (Object[]) object; int arrayLength = arrays.length; checkCollectionAndMapAndArray(arrayLength, equalLength, minLength, maxLength, fieldName, isLengthAn); for (int k = 0; isValuesAn && arrayLength > 0 && k < arrayLength; k++) { checkObject(arrays[k], String.format(ILLEGAL_FIELD_ERROR_STR, fieldName)); } } else if (valueField != null) { // 如果注解不为空就检验该类 checkObject(object, null); } } } } /** * 集合类型、Map类型、数组元素个数校验 * * @param collectionSize * @param equalLength * @param minLength * @param maxLength * @param fieldName * @param isLengthAn */ private static void checkCollectionAndMapAndArray(int collectionSize, int equalLength, int minLength, int maxLength, String fieldName, boolean isLengthAn) { // 检验元素个数是否小于最小值 checkBoolean(isLengthAn && minLength != 0 && collectionSize < minLength, String.format(ILLEGAL_MIN_SIZE_STR, fieldName, minLength)); // 检验元素个数是否大于最大值 checkBoolean(isLengthAn && maxLength != 0 && collectionSize > maxLength, String.format(ILLEGAL_MAX_SIZE_STR, fieldName, maxLength)); // 检验元素个数是否等于固定值 checkBoolean(isLengthAn && equalLength != 0 && collectionSize != equalLength, String.format(ILLEGAL_EQUAL_SIZE_STR, fieldName, minLength)); } /** * 比较基本数据类型 封装数据类型 * * @param object * @param type * @param maxValue * @param minValue * @param equalValue * @param filedName */ private static void compareNumber(Object object, Class> type, String maxValue, String minValue, String equalValue, String filedName) { boolean isMaxValue = false; boolean isMinValue = false; boolean isEqualValue = false; if (Integer.class.equals(type) || int.class.equals(type)) { Integer into = (Integer) object; into = into == null ? 0 : into; isMaxValue = !"".equals(maxValue) && Integer.valueOf(maxValue) < into; isMinValue = !"".equals(minValue) && Integer.valueOf(minValue) > into; isEqualValue = !"".equals(equalValue) && !Integer.valueOf(equalValue).equals(into); } else if (Long.class.equals(type) || long.class.equals(type)) { Long into = (Long) object; into = into == null ? 0 : into; isMaxValue = !"".equals(maxValue) && Long.valueOf(maxValue) < into; isMinValue = !"".equals(minValue) && Long.valueOf(minValue) > into; isEqualValue = !"".equals(equalValue) && !Long.valueOf(equalValue).equals(into); } else if (Short.class.equals(type) || short.class.equals(type)) { Short into = (Short) object; into = into == null ? 0 : into; isMaxValue = !"".equals(maxValue) && Short.valueOf(maxValue) < into; isMinValue = !"".equals(minValue) && Short.valueOf(minValue) > into; isEqualValue = !"".equals(equalValue) && !Short.valueOf(equalValue).equals(into); } else if (Double.class.equals(type) || double.class.equals(type)) { Double into = (Double) object; into = into == null ? 0 : into; isMaxValue = !"".equals(maxValue) && Double.valueOf(maxValue) < into; isMinValue = !"".equals(minValue) && Double.valueOf(minValue) > into; isEqualValue = !"".equals(equalValue) && !Double.valueOf(equalValue).equals(into); } else if (Float.class.equals(type) || float.class.equals(type)) { Float into = (Float) object; into = into == null ? 0 : into; isMaxValue = !"".equals(maxValue) && Float.valueOf(maxValue) < into; isMinValue = !"".equals(minValue) && Float.valueOf(minValue) > into; isEqualValue = !"".equals(equalValue) && !Float.valueOf(equalValue).equals(into); } checkBoolean(isMinValue, String.format(ILLEGAL_MIN_VALUE_STR, filedName, minValue)); checkBoolean(isMaxValue, String.format(ILLEGAL_MAX_VALUE_STR, filedName, maxValue)); checkBoolean(isEqualValue, String.format(ILLEGAL_EQUAL_VALUE_STR, filedName, equalValue)); }}
主要就是注解类和注解工具类李阿敏判断逻辑不一样,使用的时候可以
使用工具类校验,或者通过aop调用工具类校验,实例代码就不上了,看了单个注解的,多个注解的就通了。
如果使用本代码请自测通过后使用,因为我写的不一定就是标准的。有问题的请联系我,小辉很愿意和你探讨技术问题,尽管小辉技术有点渣,但是还是有点上进心的。加油吧,打工人。
努力,学习,坚持
自定义检验注解_多注解自定义参数校验相关推荐
- e0312 不存在用户定义的_更加灵活的参数校验,Spring-boot自定义参数校验注解
上文我们讨论了如何使用@Min.@Max等注解进行参数校验,主要是针对基本数据类型和级联对象进行参数校验的演示,但是在实际中我们往往需要更为复杂的校验规则,比如注册用户的密码和确认密码进行校验,这个时 ...
- 注解_自定义注解_元注解
* 元注解:用于描述注解的注解 * @Target:描述注解能够作用的位置* ElementType取值:* TYPE:可以作用于类上* METHOD:可以作用于方法上* FIELD:可以作用于成员变 ...
- java注释和注解_注释注解JAVA注解
发一下牢骚和主题无关: package anno; import java.lang.annotation.Retention; import java.lang.annotation.Retenti ...
- 注解(7)_元注解_元注解的概念_@Retention_@Target_@Documented_@Inherited
元注解的概念 元注解是用于修饰其他注解的注解. (1)元注解本身也是注解. (2)元注解是用来修饰别的注解的. JDK5.0提供了四种元注解: @Retention @Target @Document ...
- java属性注解_【java自定义注解1】java自定义注解-属性
关于自定义注解,以前项目种应用的不多,最近看新项目过程中发现了挺多自定义注解相关内容,使用起来比较巧妙,于是 总结了两种方式,记录如下: 第一种:结合反射进行属性注入,代码如下: 1.定义一个注解: ...
- java 扫描自定义注解_利用spring 自定义注解扫描 找出使用自定义注解的类
我们常常有扫描项目里带有指定注解的class, 下面是利用spring扫描自定义注解的方法, 还是比较灵活的 我这里将扫描到的class放到map, 你可以放到其他地方,以便后期使用 import l ...
- java bean value注解_@Value 注解详解
@Value 注解可以用来将外部的值动态注入到 Bean 中,在 @Value 注解中,可以使用 ${} 或 #{}.${} 与 #{} 的区别如下: (1)@Value("${}" ...
- psql where里有自定义函数慢_使用gplearn自定义特征自动生成模块
背景:数据科学领域中,数据一直都是主要驱动力,特征工程作为其中重要一环,成为无论是kaggle类的数据竞赛,还是工业界应用中关注的重点.特征工程中有重要的一个环节叫做特征融合,好的特征融合能帮助构造当 ...
- java path 注解_@PathVariable注解的使用和@Requestparam
一. @PathVariable @PathVariable这是一个路径映射格式的书写方式注解,在类映射路径的后加上/{对应方法参数中属性@PathVariable("code") ...
最新文章
- feignclient多个配置_@FeignClient同一个name使用多个配置类的解决方案
- Attach()和Detach()函数
- 河北传媒学院计算机专业分数线,河北传媒学院2019年各省各专业录取分数
- Java类和对象基础题_java类和对象基础题2
- java定义矩形类rect_Java定义矩形类
- python函数的组成要素_python函数要素有哪些?这7点是你写好python代码的关键
- CnForums国庆特别版
- python对象_查找Python对象具有的方法
- vim命令模式和底线_人生苦短!老鸟带你用Vim偷懒!
- 深度学习自学(二十二):人脸检测人脸识别-嵌入式平台方案汇总
- bzoj 3196二逼平衡树 线段树套平衡树
- Opencv安装与环境配置
- matlab2021a下载安装
- python求自定义函数的导数
- 焦点较中的网络视频相关
- 重磅!这可能是史上最全的AI产业链地图了
- pandas用法小结
- python--绘制WRF模式近地面风场以及辐射
- VMWare 移动Linux CentOS 7虚拟机后连不上网怎么办
- 拉格朗日乘数法 对y的偏导数的推导 (有点牵强,作为理解吧)