return error怎么定义_自定义一个注解校验接口参数

这段时间封装了很多的sdk,有一些sdk要求请求参数做验证,由于封装sdk肯定是用到第三方的依赖越少越好,所以自己不才写了一个注解的校验,本版本校验没有给出自定一点message,如果要可以自己加上,修改一下即可。下面就说一下这个怎么实现的吧:

一:注解类:

注解类代码如下:

package com.blog.annotation.one;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.Target;import static java.lang.annotation.ElementType.FIELD;import static java.lang.annotation.RetentionPolicy.RUNTIME;/** * @author 哲思小辉 * @className CheckNull * @description 校验参数一个注解 * @createTime 2020年7月30日 16:48:38 */@Target({FIELD, ElementType.TYPE, ElementType.PARAMETER})@Retention(RUNTIME)public @interface CheckNull {/**     * 是否校验为null     *     * @return     */boolean notNull() default false;/**     * 默认检查为空     *     * @return     */boolean notEmpty() default false;/**     * 长度最小值,集合最小值,map键最小个数     *     * @return     */int minLength() default 0;/**     * 长度最大值,集合最小值,map键最大个数     *     * @return     */int maxLength() default 0;/**     * 长度固定值     *     * @return     */int equalLength() default 0;/**     * 最小值 (针对基本数据类型)     *     * @return     */String minValue() default "";/**     * 最大值 (针对基本数据类型)     *     * @return     */String maxValue() default "";/**     * 相等的值     *     * @return     */String equalValue() default "";/**     * String包含的数值, Map中必须存在的key     *     * @return     */String[] strContains() default {};/**     * 是否去除前后空格(字符串)     *     * @return     */boolean trim() default true;}

二、校验使用注解的实例对象方法

注解写好了,现在要写它的校验,如何来判断该字段是否符合注解里面定义的呢,下面就是校验的代码:

package com.blog.annotation.one;import java.lang.reflect.Field;import java.util.*;/** * @author 哲思小辉 * @className CheckNullUtil * @description 单一注解检测工具 * @createTime 2020年7月30日 16:40:52 */public final class CheckNullUtils {private CheckNullUtils() {}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);}/*** 判断为空并且如果字符串不去除空格** @param object* @param message* @throws Exception*/public static void checkNullAndEmpty(Object object, String message) throws Exception {checkNull(object, message);checkEmpty(object, message, false);}/**     * 判断为空并且如果字符串就去除前后的空格     *     * @param object     * @param message     * @throws Exception     */public static void checkNullAndTrimEmpty(Object object, String message) throws Exception {checkNull(object, message);checkEmpty(object, message, true);}/**     * 校验是不是为null     *     * @param message     * @param object     * @throws Exception     */public static void checkNull(Object object, String message) {checkBoolean(object == null, message);}/**     * 校验元素为不为空     *     * @param object     * @param message     * @param isTrim     * @throws Exception     */public static void checkEmpty(Object object, String message, boolean isTrim) {// 先检测是否为nullcheckNull(object, message);boolean isOperator = false;if (object instanceof String) {// 字符串长度为0String str = (String) object;str = isTrim ? str.trim() : str;isOperator = str.length() == 0;} else if (object instanceof Collection) {// 个数为0isOperator = ((Collection) object).isEmpty();} else if (object instanceof Map) {// 键值为空isOperator = ((Map) object).isEmpty();} else if (object.getClass().isArray()) {// 数组长度为0isOperator = ((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     * @param message     * @throws Exception     */private static void checkFields(Object req, String message) throws Exception {checkNull(req, message);Class> aClass = req.getClass();CheckNull checkNull = aClass.getAnnotation(CheckNull.class);if (checkNull != null && checkNull.notEmpty()) {checkEmpty(req, message, checkNull.trim());}// 获取里面的属性Field[] fields = aClass.getDeclaredFields();if (fields == null || fields.length == 0) {return;}for (int i = 0; fields != null && i < fields.length; i++) {Field field = fields[i];CheckNull annotation = field.getAnnotation(CheckNull.class);if (annotation != null) {int maxLength = annotation.maxLength();boolean isMax = maxLength > 0;int minLength = annotation.minLength();boolean isMin = minLength > 0;int equalLength = annotation.equalLength();boolean isEqual = equalLength > 0;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));}String nullEmptyStr = String.format(ILLEGAL_NULL_OR_EMPTY_STR, fieldName);// 如果注解中notNull为true就检验是否为nullif (annotation.notNull()) {checkNull(object, nullEmptyStr);}// 如果注解中notEmpty为true就检验是否为空if (annotation.notEmpty()) {checkEmpty(object, nullEmptyStr, checkNull.trim());}// 不为空就校验里面的参数数据if (object != null) {Class> type = field.getType();Class>[] interfaces = type.getInterfaces();Class> superclass = type.getSuperclass();String[] strings = annotation.strContains();// 获取接口HashSet> classSet = new HashSet<>(Arrays.asList(interfaces));if (type.equals(String.class)) {String str = (String) object;int length = str.length();if (annotation.trim()) {str = str.trim();}// 校验长度是不是小于最小值checkBoolean(isMin && length < minLength, String.format(ILLEGAL_MIN_LENGTH_STR, fieldName,minLength));// 校验长度是不是大于最大值checkBoolean(isMax && length > maxLength, String.format(ILLEGAL_MAX_LENGTH_STR, fieldName,maxLength));// 校验长度是否相等checkBoolean(isEqual && length != equalLength, String.format(ILLEGAL_EQUAL_LENGTH_STR,fieldName, equalLength));// 是否包含值if (strings != null) {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)) {compareNumber(object, type, annotation.maxValue(), annotation.minValue(), annotation.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 (type.isAnnotationPresent(CheckNull.class)) {// 如果是使用了NotNull注解的类进行里面参数校验checkFields(object, String.format(ILLEGAL_NULL_OR_EMPTY_STR, fieldName));} else if (classSet.contains(Collection.class)) {// 当前集合的泛型类型Collection collection = (Collection) object;int colletionSize = collection.size();checkCollectionAndMapAndArray(colletionSize, equalLength, minLength, maxLength, fieldName);if (colletionSize > 0) {for (Object o : collection) {checkObject(o, String.format(ILLEGAL_FIELD_ERROR_STR, fieldName));}}} else if (Map.class.equals(type) || classSet.contains(Map.class)) {Map map = (Map) object;int mapSize = map.size();// 校验个数是不是小于最小值checkBoolean(isMin && mapSize < minLength, String.format(ILLEGAL_MIN_SIZE_STR, fieldName, minLength));// 校验个数是不是大于最大值checkBoolean(isMax && mapSize > maxLength, String.format(ILLEGAL_MAX_SIZE_STR, fieldName, maxLength));// 校验个数是否相等checkBoolean(isEqual && mapSize != equalLength, String.format(ILLEGAL_STR, fieldName));for (int m = 0; 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);for (int k = 0; arrayLength > 0 && k < arrayLength; k++) {checkObject(arrays[k], String.format(ILLEGAL_FIELD_ERROR_STR, fieldName));}}}}}}/**     * 比较基本数据类型 封装数据类型     *     * @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));}/**     * 集合类型、Map类型、数组元素个数校验     *     * @param collectionSize     * @param equalLength     * @param minLength     * @param maxLength     * @param fieldName     */private static void checkCollectionAndMapAndArray(int collectionSize, int equalLength, int minLength,int maxLength, String fieldName) {// 检验元素个数是否小于最小值checkBoolean(minLength != 0 && collectionSize < minLength, String.format(ILLEGAL_MIN_SIZE_STR,fieldName,minLength));// 检验元素个数是否大于最大值checkBoolean(maxLength != 0 && collectionSize > maxLength, String.format(ILLEGAL_MAX_SIZE_STR, fieldName,maxLength));// 检验元素个数是否等于固定值checkBoolean(equalLength != 0 && collectionSize != equalLength, String.format(ILLEGAL_EQUAL_SIZE_STR, fieldName,minLength));}}

可以看到对长度,是否为null,为空,个数,数值大小都做了校验,满足大多数的需求,可能需要一些特殊类型数据的校验就自行加就OK了。注解和校验类都写好了现在就是测试的时候了,

三、测试一波

Person类 代码忽略set,get方法了哦

public class Person {@CheckNull(trim = true, minLength = 2, maxLength = 5)private String name;private List list;@CheckNullprivate Test[] tests;@CheckNull(minLength = 2)private Integer[] integers;@CheckNull(minLength = 3)private Double[] ints;@CheckNullprivate Test test;@CheckNull(minValue = "3", strContains = {"3.222", "3.88"})private float a;@CheckNull(minValue = "2")private Integer b;@CheckNull(strContains = {"a", "b"}, minLength = 2, maxLength = 2)private HashMap map;@CheckNull(minLength = 2, maxLength = 3)private Map map2;public Person(String name, List list, int a, Integer b, HashMap map, Map map2) {this.name = name;this.list = list;this.a = a;this.b = b;this.map = map;this.map2 = map2;}} 

test类也忽略了set,get方法了哦

public class Test {private Integer age;private String name;public static void main(String[] args) throws Exception {List lists = new ArrayList<>();lists.add("a");HashMapmap = new HashMap<>();map.put("a", "df");Person a = new Person("        ", lists, 1, 1, map, map);a.setTest(new com.blog.annotation.one.Test());a.setA(3.88f);a.setInts(new Double[]{});CheckNullUtils.checkObject(a, "请求参数为空");}}

测试的时候把

checkBoolean这个抛出异常的注释了,所有的异常都是该方法的抛出

结果为:

d0ff9872ce37c8e8b610de3aba8a759d.png

校验结果还可以吧,自己觉得把错误信息修改成英文可能逼格会高点,这种高逼格的事情就留给你们去做了,我还是喜欢低调点,谁让我渣呢,没有办法,继续学习,一起加油。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值