美文网首页
java优雅的处理必填校验

java优雅的处理必填校验

作者: 任未然 | 来源:发表于2021-03-19 15:16 被阅读0次

    一. 概述

    在开发后端接口, 通常都会涉及检验参数必填校验, 一般我们的处理都是很粗暴的写个if()判断, 然后抛异常. 本文将介绍通过代理的思想, 用注解优雅的处理非空判断

    二. 实现过程

    最终想要的效果->在方法的参数加个注解或者参数的属性里加个注解, 注解可以自定义报错信息, 就可以实现自动非空校验

    2.1 编写注解

    @Target({ElementType.FIELD,ElementType.PARAMETER})  //作用的位置
    @Retention(RetentionPolicy.RUNTIME) //作用域
    @Documented
    public @interface NotNull {
        String value() default "{报错信息}";
    }
    

    说明: 该注解用来绑定某个必填属性

    @Target({ElementType.TYPE,ElementType.METHOD})  //作用的位置
    @Retention(RetentionPolicy.RUNTIME) //作用域
    @Documented
    public @interface CheckParam {
    }
    

    说明: 该注解用来绑定某个类或某个方法,作为校验代理拦截的标识

    2.2 编写校验代理AOP

    @Aspect
    @Slf4j
    public class CheckParamAop {
        @Around("@within(com.midea.cloud.common.annotation.CheckParam) || @annotation(com.midea.cloud.common.annotation.CheckParam)")
        public Object cacheClear(ProceedingJoinPoint pjp) throws Throwable {
            try {
                MethodSignature signature = (MethodSignature) pjp.getSignature();
                // 方法参数注解类型
                Annotation[][] parameterAnnotations = signature.getMethod().getParameterAnnotations();
                // 方法参数的类型
                Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
                // 获取方法参数
                Object[] args = pjp.getArgs();
                if(!ObjectUtils.isEmpty(args)){
                    // 遍历参数
                    AtomicInteger index = new AtomicInteger(0);
                    Arrays.stream(args).forEach(o -> {
                        int indexNo = index.getAndAdd(1);
                        /**
                         * 检查方法参数非空
                         */
                        Annotation[] parameterAnnotation = parameterAnnotations[indexNo];
                        if(!ObjectUtils.isEmpty(parameterAnnotation)){
                            Arrays.stream(parameterAnnotation).forEach(annotation -> {
                                if(annotation instanceof NotNull){
                                    NotNull notNull = (NotNull)annotation;
                                    // 注解信息
                                    String message = notNull.value();
                                    // 通过工具类获取多语言信息
                                    String localeMsg = LocaleHandler.getLocaleMsg(message);
                                    // 检查参数非空
                                    Optional.ofNullable(o).
                                            filter(o1 -> !ObjectUtils.isEmpty(o1)).
                                            orElseThrow(()->new BaseException(localeMsg));
                                }
                            });
                        }
    
                        /**
                         * 检查方法参数属性非空
                         */
                        Class<?> parameterType = parameterTypes[indexNo];
                        Field[] fields = parameterType.getDeclaredFields();
                        if(!ObjectUtils.isEmpty(fields)){
                            // 遍历属性
                            Arrays.stream(fields).forEach(field -> {
                                NotNull annotation = field.getAnnotation(NotNull.class);
                                if(null != annotation){
                                    Object value = null;
                                    // 注解信息
                                    String message = annotation.value();
                                    // 通过工具类获取多语言信息
                                    String localeMsg = LocaleHandler.getLocaleMsg(message);
                                    Optional.ofNullable(o).orElseThrow(()->new BaseException(localeMsg));
                                    try {
                                        field.setAccessible(true);
                                        value = field.get(o);
                                    } catch (Exception e) {
                                        log.error("获取属性值报错"+e.getMessage());
                                        log.error("获取属性值报错"+e);
                                    }
                                    // value为空时报错
                                    Optional.ofNullable(value).
                                            filter(o1 -> !ObjectUtils.isEmpty(o1)).
                                            orElseThrow(()->new BaseException(localeMsg));
                                }
                            });
                        }
                    });
                }
            } catch (BaseException e) {
                throw e;
            } catch (Exception e){
                log.error("检查参数aop报错:"+e.getMessage());
                log.error("检查参数aop报错:"+e);
            }
            return pjp.proceed();
        }
    }
    

    三. 使用示例

    public class Test{
        @Data
        class Demo{
            @NotNull("名字不能为空!")
            private String name;
            private String sex;
            private Integer age;
        }
    
        @CheckParam
        public void testNoNullCheck1(Demo demo) {
    
        }
        @CheckParam
        public void testNoNullCheck2(@NotNull("user不能为空") User user) {
    
        }
    }
    

    相关文章

      网友评论

          本文标题:java优雅的处理必填校验

          本文链接:https://www.haomeiwen.com/subject/vdmvcltx.html