框架介绍

mikilin 结合spring项目

2020-05-28  本文已影响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

上一篇下一篇

猜你喜欢

热点阅读