自定义异常注解处理框架
首先我们定义两个用于检验string和List的注解
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** @author caiyi.yu* 自定义非空判断*/ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface StringNotBlank {String message() default "该字段不能为空";String name() default ""; }
package com.mija.tpa.platform.api.myannotate;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** @author caiyi.yu*/ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ListNotEmpty {String message() default "list不能为空"; }
接下来,我们可以定义一个validateHelper,用于通过反射使用我们自定义注解校验规则
import com.mija.tpa.platform.api.myannotate.ListNotEmpty; import com.mija.tpa.platform.api.myannotate.StringNotBlank; import lombok.extern.slf4j.Slf4j;import java.lang.reflect.Field; import java.util.HashMap; import java.util.List; import java.util.function.BiConsumer;/*** @author caiyi.yu<br>* <b>ValidateHelper </b>用于验证对象字段 <br>* 使用方式:手动调用validate,这是验证参数的入口<br>* 已经支持的类型:String、List<br>* 如果需要添加需要支持的其他类型的验证,请在HANDLERS中添加一个合适的处理器并在这个类中实现他<br>*/ @Slf4j public class ValidateHelper {@FunctionalInterfacepublic interface ThrowingBiConsumer<T, U> {void accept(T t, U u) throws Exception;}private static <T, U> BiConsumer<T, U> wrapException(ThrowingBiConsumer<T, U> throwingBiConsumer) {return (t, u) -> {try {throwingBiConsumer.accept(t, u);} catch (Exception e) {throw new RuntimeException(e); // 将异常统一化抛出}};}private static final HashMap<Class<?>, BiConsumer<Object, Field>> HANDLERS = new HashMap<>();static {HANDLERS.put(String.class, wrapException(ValidateHelper::validateString));HANDLERS.put(List.class, wrapException(ValidateHelper::validateList));}/*** 校验入参的字段*/public static void validate(Object obj) throws IllegalAccessException {if (obj == null){return;}Class<?> clazz = obj.getClass();for (Field field : clazz.getDeclaredFields()) {BiConsumer<Object, Field> handler = HANDLERS.getOrDefault(field.getType(), ValidateHelper::defaultHandler);handler.accept(obj, field);}}/*** 校验 String 类型的字段是否为空*/private static void validateString(Object obj, Field field) throws IllegalAccessException {if (field.isAnnotationPresent(StringNotBlank.class)) {field.setAccessible(true);String value =(String) field.get(obj);if (value == null || value.isEmpty()) {StringNotBlank fieldAnnotation = field.getAnnotation(StringNotBlank.class);throw new IllegalArgumentException(field.getName() + ":" + fieldAnnotation.message());}}}/*** 校验 List 类型的字段是否为空*/private static void validateList(Object obj, Field field) throws IllegalAccessException {if (field.isAnnotationPresent(ListNotEmpty.class)) {field.setAccessible(true);List<?> value =(List<?>) field.get(obj);if (value == null || value.isEmpty()) {ListNotEmpty fieldAnnotation = field.getAnnotation(ListNotEmpty.class);throw new IllegalArgumentException(field.getName() + ":" + fieldAnnotation.message());}else {// 遍历列表中的每个元素进行校验for (Object item : value) {validate(item);}}}//对集合元素的深入处理else {field.setAccessible(true);List<?> value =(List<?>) field.get(obj);if (value != null && !value.isEmpty()){for (Object item : value) {validate(item);}}}}/*** 默认处理器,当没有找到对应的字段类型处理器时调用*/private static void defaultHandler(Object obj, Field field) {log.warn("【ValidateHelper】未定义的校验类型!字段类型:" + field.getType());} }