注解接口实战记录

项目场景:

在项目开发的过程当中,我们想通过注解标识的形式实现,那些接口需要记录日志。本项目是基于SpringBoot框架的基础之上记录,注解在实战用的应用。

 操作步骤

1、编写@interface注解类

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
    /**
     * 操作
     */
    public OperationTypeEnum operatorType() default OperationTypeEnum.SELECT;

    /**
     * 是否保存请求的参数
     */
    public boolean isSaveRequestData() default true;
    /**
     * 是否保存响应的参数
     */
    public boolean isSaveResponseData() default true;
    /**
     * 备注信息
     */
    public String remarks() default "";
}

2、编写切面处理类

@Aspect
@Component
public class LogAspect {
  
    @Pointcut("@annotation(com.xyy.annotation.LogAnnotation)")
    public void logPointCut() {
    }

    @AfterReturning(pointcut = "@annotation(log)", returning = "ret")
    public void doAfterReturning(JoinPoint joinPoint, LogAnnotation log, Object ret) {
        handleLog(joinPoint, log, ret);
    }

    @AfterThrowing(value = "@annotation(log)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, LogAnnotation log, Exception e) {
        handleLException(joinPoint,log,e);
    }

    /**
     * 处理请求返回信息
     */
    protected void handleLog(JoinPoint joinPoint, LogAnnotation log, Object ret) {
        HttpServletRequest request = ServletUtils.getRequest();
        String ipAddress = IpUtils.getIpAddr(request);//IP 地址
        LoginUser loginUser = tokenUtils.getLoginUser(request); //用户信息,暂时不处理
        BusLog busLog = packageBusLog(joinPoint, ipAddress, log, loginUser);
        String responseParameters = JSONUtil.toJsonStr(ret);//返回参数字符串
        busLog.setResponseParam(responseParameters.getBytes(StandardCharsets.UTF_8));
        busLogService.save(busLog);
    }

    /**
     * 处理请求异常信息
     */
    protected void handleLException(JoinPoint joinPoint, LogAnnotation log, Exception e) {
        HttpServletRequest request = ServletUtils.getRequest();
        LoginUser loginUser = tokenUtils.getLoginUser(request); //用户信息,暂时不用处理
        String ipAddress = IpUtils.getIpAddr(request);//IP 地址
        BusLog busLog = packageBusLog(joinPoint, ipAddress, log, loginUser);
        busLog.setExceptionInfo(e.getMessage());
        busLogService.save(busLog);
    }

    /**
     * 处理请求参数,封装请求参数为JSON字符串
     */
    protected static Map<String, String> handleRequestParameters(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature) signature;
        String[] parameterNames = methodSignature.getParameterNames(); /**获取方法签名*/
        Type[] genericParameterTypes =   methodSignature.getMethod().getGenericParameterTypes();/**获取所有的参数类型*/
        Map resultMap = new HashMap();
        for (int i = 0; i < args.length; i++) {
            System.out.println("参数类型--------------->" + genericParameterTypes[i]);
            System.out.println(parameterNames[i]);
            System.out.println(JSONUtil.toJsonStr(args[i]));
            if (foundationType(genericParameterTypes[i].toString())) {
                resultMap.put(parameterNames[i], args[i]);
            } else {
                resultMap.put(parameterNames[i], JSONUtil.toJsonStr(args[i]));
            }
        }
        return resultMap;
    }

    /**
     * 处理JSONUtils中把基础类型数据转换成{}对象的问题,JSON传递Interger和Long的时,JSONUtil.toJsonStr()处理不了
     */
    protected static boolean foundationType(String params) {
        if (params.indexOf("Long") > -1) {
            return true;
        }
        if (params.indexOf("long") > -1) {
            return true;
        }
        if (params.indexOf("Integer") > -1) {
            return true;
        }
        if (params.indexOf("int") > -1) {
            return true;
        }
        return false;
    }
 
}

3、使用方法 

使用方法:在方法上标识注解标识,补充自己定义的注解标识字段对应的值。
 @LogAnnotation(operatorType = OperationTypeEnum.SELECT) /**注意:这里=前面的是自定义注解的方法名,如果是枚举类型的话,处理类中获取对应的值(本例子中,在切面类中获取枚举对应的值)*/
    @Override
    public AjaxResult bookInfo(BooKInfoRequest booKInfoRequest) {
        BookInfo bookInfo = httpRequestUtils.queryBookInfo(booKInfoRequest.getBarCode());
        LoginUser loginUser = tokenUtils.getLoginUser(ServletUtils.getRequest());
        System.out.println(JSONUtil.toJsonStr(loginUser));
        BookInfoResponse  bookInfoResponse =  new BookInfoResponse();
        String []  ignoreProperties={"createTime","dueDate","holdPickupDate","recallDate","transactionDate","updateTime"};
        Date transactionDate = DateUtil.parse(bookInfo.getTransactionDate().replaceAll(" ",""));
        BeanUtil.copyProperties(bookInfo,bookInfoResponse,ignoreProperties);
        bookInfoResponse.setTransactionDate(transactionDate);
        System.out.println(JSONUtil.toJsonStr(bookInfoResponse));
        return AjaxResult.success(bookInfoResponse);
    }

 


填坑总结:

1、自定义注解类中定义的都是方法(自己编写的时候,写成了属性,各位大佬见笑)。

2、枚举类中获取参数的时候,在业务处理类中获取枚举类对应的参数

3、Hutool使用过程中,遇到前端传来的参数是Long或者Integer相关的变量时,在使用JSONUtil.toJsonStr()时,返回是空。

4、在handleRequestParameters()方法中,可以通过joinPoint获取相关参数的的方式,有需要的同学可以自取。

5、BeanUtil 工具在使用的过程当中可以忽略默写字段不进行属性值的copy。 BeanUtil.copyProperties(bookInfo,bookInfoResponse,ignoreProperties);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值