美文网首页框架介绍
mikilin 结合spring项目

mikilin 结合spring项目

作者: 老柿子 | 来源:发表于2020-05-28 20:17 被阅读0次

    mikilin 结合spring项目

    mikilin框架相当于一个工具类核查的框架,如果要放在项目中,作为Controller层作为基本的核查层,那么可以这么做(由于mikilin暂时还没有跟spring项目做适配,自己使用的时候,可以参考如下这样写)

    一、新增自动核查注解

    可以修饰类,函数,以及Controller中的参数

    import java.lang.annotation.*;
    
    /**
     * 修饰函数和参数,用于属性的核查
     *
     * <p>
     *     <ul>
     *         <li>1.修饰类:则会核查类下面所有函数的所有参数</li>
     *         <li>2.修饰函数:则会核查函数对应的所有参数</li>
     *         <li>3.修饰参数:则只会核查指定的参数</li>
     *     </ul>
     * @author robot
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
    public @interface AutoCheck {
    
        /**
         * 分组
         */
        String group() default "_default_";
    }
    

    二、aop解析核查

    下面代码直接拷贝即可,但是有些地方有道了自己的框架Neo,可以自己替换掉,其中NeoMap就是个普通的Map<String, Object>对象,其中的TimeRangeStrUrl是一个时间转换为中文的计算工具,如果不想使用Neo框架的话我会列在其他文件中

    @Slf4j
    @Aspect
    @Component
    public class ControllerAop {
    
        /**
         * 拦截方法中添加注解{@link EnableAopLog}的方法
         */
        @Around("@annotation(com.isyscore.walle.admin.aop.EnableAopLog)")
        public Object aroundEnableLog(ProceedingJoinPoint pjp) throws Throwable {
            Method currentMethod = getMethod(pjp);
            EnableAopLog enableAopLog = currentMethod.getDeclaredAnnotation(EnableAopLog.class);
            long start = System.currentTimeMillis();
            NeoMap outInfo = NeoMap.of();
            // 函数名字
            String funStr = pjp.getSignature().toLongString();
            outInfo.put("fun", funStr);
    
            // 参数的值
            outInfo.put("parameters", getParameters(pjp));
            Object result = null;
            try {
                result = pjp.proceed();
                outInfo.put("result", result);
            } catch (Exception e) {
                outInfo.put("timeout", TimeRangeStrUtil.parseTime(System.currentTimeMillis() - start));
                log.error(JSON.toJSONString(outInfo), e);
                return result;
            }
    
            outInfo.put("timeout", TimeRangeStrUtil.parseTime(System.currentTimeMillis() - start));
            if (enableAopLog.enable()) {
                log.info(JSON.toJSONString(outInfo));
            }
            return result;
        }
    
        /**
         * 拦截controller中所有的方法
         */
        @Around("execution(* com.isyscore.walle.admin.web.controller.*.*(..))")
        public Object aroundParameter(ProceedingJoinPoint pjp) {
            long start = System.currentTimeMillis();
            String funStr = pjp.getSignature().toLongString();
            Object result;
            Method currentMethod = getMethod(pjp);
            try {
                validate(pjp);
                result = pjp.proceed();
            } catch (Throwable e) {
                NeoMap outInfo = NeoMap.of();
                outInfo.put("fun", funStr);
                outInfo.put("parameters", getParameters(pjp));
                outInfo.put("timeout", TimeRangeStrUtil.parseTime(System.currentTimeMillis() - start));
                outInfo.put("errMsg", e.getMessage());
                log.error("后端异常:" + outInfo.toString(), e);
                Class<?> returnClass = currentMethod.getReturnType();
                if (e instanceof BusinessException) {
                    if (Response.class.isAssignableFrom(returnClass)) {
                        BusinessException businessException = (BusinessException) e;
                        return Response.fail(businessException.getErrCode(), businessException.getMessage());
                    } else {
                        return null;
                    }
                } else {
                    if (Response.class.isAssignableFrom(returnClass)) {
                        return Response.fail(HttpStatus.INTERNAL_SERVER_ERROR.toString(), e.getMessage());
                    } else {
                        return null;
                    }
                }
            }
            return result;
        }
    
        private List<Object> getParameters(ProceedingJoinPoint pjp) {
            List<Object> parameters = new ArrayList<>();
            Object[] args = pjp.getArgs();
            for (Object arg : args) {
                if (arg instanceof ServletRequest || arg instanceof ServletResponse || arg instanceof MultipartFile) {
                    continue;
                }
                parameters.add(arg);
            }
            return parameters;
        }
    
        @SuppressWarnings("all")
        private void validate(ProceedingJoinPoint pjp) {
            Signature sig = pjp.getSignature();
            MethodSignature methodSignature;
            if (!(sig instanceof MethodSignature)) {
                throw new IllegalArgumentException("该注解只能用于方法");
            }
            methodSignature = (MethodSignature) sig;
            Method currentMethod;
            try {
                currentMethod = pjp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
            } catch (NoSuchMethodException e) {
                throw new BusinessException(e);
            }
    
            if (currentMethod.getDeclaringClass().isAnnotationPresent(AutoCheck.class)) {
                doValidate(pjp);
            } else if (currentMethod.isAnnotationPresent(AutoCheck.class)) {
                doValidate(pjp);
            } else {
                Parameter[] parameters = currentMethod.getParameters();
                Object[] args = pjp.getArgs();
                for (int index = 0; index < args.length; index++) {
                    if (args[index] instanceof ServletRequest || args[index] instanceof ServletResponse || args[index] instanceof MultipartFile) {
                        continue;
                    }
    
                    if (parameters[index].isAnnotationPresent(AutoCheck.class)) {
                        try {
                            MkValidators.validate(args[index]);
                        } catch (MkCheckException e) {
                            throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.toString(), "参数核查异常:" + MkValidators.getErrMsg());
                        }
                    }
                }
            }
        }
    
        @SuppressWarnings("all")
        private void doValidate(ProceedingJoinPoint pjp) {
            Object[] parameters = pjp.getArgs();
            for (Object parameter : parameters) {
                try {
                    MkValidators.validate(parameter);
                } catch (MkCheckException e) {
                    String checkErr = "参数核查异常:" + MkValidators.getErrMsg();
                    throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.toString(), checkErr);
                }
            }
        }
    
        private Method getMethod(ProceedingJoinPoint pjp) {
            Signature sig = pjp.getSignature();
            MethodSignature methodSignature;
            if (!(sig instanceof MethodSignature)) {
                throw new IllegalArgumentException("该注解只能用于方法");
            }
            methodSignature = (MethodSignature) sig;
            Method currentMethod;
            try {
                currentMethod = pjp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
            } catch (NoSuchMethodException e) {
                throw new BusinessException(e);
            }
            return currentMethod;
        }
    }
    

    三、Controller使用

    1.修饰类

    @AutoCheck
    @RequestMapping("walle/maven/config")
    @RestController
    public class MavenConfigController extends BaseResponseController {
    
        @Autowired
        private MavenConfigService mavenConfigservice;
    
        /**
         * 新增maven依赖项
         */
        @PostMapping("insertMavenItem")
        public Response<Integer> insertMavenItem(@RequestBody MavenItemInsertReq mavenItemInsertReq) {
            return success(mavenConfigservice.insertMavenItem(mavenItemInsertReq));
        }
    }
    

    则该类中的任何方法对应的参数都会被核查,比如上面的参数类型MavenItemInsertReq该类型的核查就是直接采用Mikilin的注解即可

    2.修饰方法

    则只有该方法会核查,其他的不会

    @RequestMapping("walle/maven/config")
    @RestController
    public class MavenConfigController extends BaseResponseController {
    
        @Autowired
        private MavenConfigService mavenConfigservice;
    
        /**
         * 新增maven依赖项
         */
        @AutoCheck
        @PostMapping("insertMavenItem")
        public Response<Integer> insertMavenItem(@RequestBody MavenItemInsertReq mavenItemInsertReq) {
            return success(mavenConfigservice.insertMavenItem(mavenItemInsertReq));
        }
    }
    

    3.修饰参数

    @RequestMapping("walle/maven/config")
    @RestController
    public class MavenConfigController extends BaseResponseController {
    
        @Autowired
        private MavenConfigService mavenConfigservice;
    
        /**
         * 新增maven依赖项
         */
        @PostMapping("insertMavenItem")
        public Response<Integer> insertMavenItem(@AutoCheck @RequestBody MavenItemInsertReq mavenItemInsertReq) {
            return success(mavenConfigservice.insertMavenItem(mavenItemInsertReq));
        }
    }
    

    具体的核查方式见Mikilin文档
    简书:https://www.jianshu.com/p/e7f212afa578
    语雀:https://www.yuque.com/simonalong/mikilin/mduu3z
    其中TimeRangeStrUtl工具类,见这里:https://www.jianshu.com/p/67b189caab9f

    相关文章

      网友评论

        本文标题:mikilin 结合spring项目

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