AOP实现API调用简单验证、日志记录、异常处理

AOP实现API调用简单验证、日志记录、异常处理
1.添加maven依赖
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
2.创建切面类
/**
 * @description: API切面处理类
 * @author: wzg
 * @create: 2022-01-06
 **/
@Aspect
@Component
public class SjztDynamicApiAspect {


    @Resource
    private SjztDynamicApiLogService sjztDynamicApiLogService;

    @Resource
    private SjztDynamicApiUserService sjztDynamicApiUserService;

    @Resource
    private SjztDynamicApiWhitelistService sjztDynamicApiWhitelistService;
}
3.实现简单API调用认证
 
	/**
     * 设置切入点 进行动态API调用验证
     */
    @Pointcut("execution(* com.yeyoo.sjzt.platform.controller.rest.SjztUserServiceRestController.exec(..))")
    public void apiUserFilter() {

    }
    
     /**
     * 调用动态API前,进行用户认证
     * @param joinPoint
     */
    @Before(value = "apiUserFilter()")
    public void userFilter(JoinPoint joinPoint) {
        // 获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 获取请求参数ak、sn
        String ak = request.getParameter("ak");
        String sn = request.getParameter("sn");


        if(ak==null||ak.equals("")||sn==null||sn.equals("")){
            throw new DynamicApiException(ResultCode.BAD_REQUEST,"缺少请求参数");
        }

        String userName = "";
        String sk = "";

        // 判断服务平台用户是否已创建
        SjztDynamicApiUser user = sjztDynamicApiUserService.selectApiUser(ak);
        if(user==null){
            throw new DynamicApiException(ResultCode.UNAUTHORIZED,"用户未授权,请联系服务平台管理员");
        }else {
            userName = user.getUserName();
            sk = user.getSeckey();
        }

        // 获取被调用的签名
        Signature signature = joinPoint.getSignature();
        // 转换为方法签名
        MethodSignature methodSignature = (MethodSignature) signature;
        // 获取 controller 的方法
        Method method = methodSignature.getMethod();
        // 获取serviceApi
        com.yeyoo.dynamic.api.beans.DynamicApiExecRequest reqMap = (DynamicApiExecRequest) getParameter(method, joinPoint.getArgs());
        String serviceApi = reqMap.getServiceApi();

        // 判断用户是否在接口白名单中
        SjztDynamicApiWhitelist whitelist = sjztDynamicApiWhitelistService.selectApiWhitelist(serviceApi,userName);
        if(whitelist==null){
            throw new DynamicApiException(ResultCode.FORBIDDEN,"接口未授权,请联系服务平台管理员");
        }

        // 拼接未加密字符串
        String str = ********;

        // 加密字符串获得本地sn
        String localSn = ************;

        // 对比参数sn和localSn
        if(!localSn.equals(sn)){
            throw new DynamicApiException(ResultCode.VALIDATE_FAILED,"sn校验失败");
        }

    }
    
4.调用日志记录
	/**
     * 设置操作日志切入点 记录调用日志
     */
    @Pointcut("execution(* com.yeyoo.sjzt.platform.controller.rest.SjztUserServiceRestController.exec(..))")
    public void apiLog() {

    }

	/**
     * 正常返回日志记录
     * @param joinPoint
     * @param responseBody
     */
    @AfterReturning(value = "apiLog()", returning = "responseBody")
    public void saveApiLog(JoinPoint joinPoint, Object responseBody) {

        // 获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        SjztDynamicApiLog sjztDynamicApiLog = new SjztDynamicApiLog();

        // 获取被调用的签名
        Signature signature = joinPoint.getSignature();
        // 转换为方法签名
        MethodSignature methodSignature = (MethodSignature) signature;
        // 获取 controller 的方法
        Method method = methodSignature.getMethod();

        // 获取Status Code
        com.yeyoo.sjzt.beans.ResultData resMap = (ResultData) responseBody;
        Integer code = resMap.getCode();

        // 获取动态接口名称
        com.yeyoo.dynamic.api.beans.DynamicApiExecRequest reqMap = (DynamicApiExecRequest) getParameter(method, joinPoint.getArgs());
        String apiName = reqMap.getServiceApi();

        // 动态接口调用日志组装入库
        sjztDynamicApiLog.setCode(code);
        sjztDynamicApiLog.setApiName(apiName);
        sjztDynamicApiLog.setMethod(request.getMethod());
        sjztDynamicApiLog.setRequestBody(JSON.toJSONString(getParameter(method, joinPoint.getArgs())));
        sjztDynamicApiLog.setResponseBody(JSON.toJSONString(responseBody));

        sjztDynamicApiLogService.addApiLog(sjztDynamicApiLog);
    }


	/**
     * 根据方法和传入的参数获取请求参数
     */
    private Object getParameter(Method method, Object[] args) {
        List<Object> argList = new ArrayList<>();
        //获取方法的参数
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            //将 RequestBody 注解修饰的参数作为请求参数
            RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
            if(requestBody != null){
                argList.add(args[i]);
            }
            //将 RequestParam 注解修饰的参数作为请求参数
            RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
            if (requestParam != null) {
                Map<String, Object> map = new HashMap<>();
                String key = parameters[i].getName();
                if (!StringUtils.isEmpty(requestParam.value())) {
                    key = requestParam.value();
                }
                map.put(key, args[i]);
                argList.add(map);
            }

        }
        if (argList.size() == 0) {
            return null;
        } else if (argList.size() == 1) {
            return argList.get(0);
        } else {
            return argList;
        }
    }
5.异常日志记录
	/**
     * 异常信息日志记录
     * @param joinPoint
     * @param exception
     */
    @AfterThrowing(value = "apiLog()", throwing = "exception")
    public void saveExceptionLog(JoinPoint joinPoint, DynamicApiException exception) {

        // 获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        SjztDynamicApiLog sjztDynamicApiLog = new SjztDynamicApiLog();

        // 获取被调用的签名
        Signature signature = joinPoint.getSignature();
        // 转换为方法签名
        MethodSignature methodSignature = (MethodSignature) signature;
        // 获取 controller 的方法
        Method method = methodSignature.getMethod();

        Integer code = exception.getErrorCode().getCode();

        // 获取动态接口名称
        com.yeyoo.dynamic.api.beans.DynamicApiExecRequest reqMap = (DynamicApiExecRequest) getParameter(method, joinPoint.getArgs());
        String apiName = reqMap.getServiceApi();

        // 动态接口调用日志组装入库
        sjztDynamicApiLog.setCode(code);
        sjztDynamicApiLog.setApiName(apiName);
        sjztDynamicApiLog.setMethod(request.getMethod());
        sjztDynamicApiLog.setRequestBody(JSON.toJSONString(getParameter(method, joinPoint.getArgs())));
        sjztDynamicApiLog.setResponseBody(JSON.toJSONString(exception.getMessage()));

        sjztDynamicApiLogService.addApiLog(sjztDynamicApiLog);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值