面向注解的切面实现

1.

package com.g2.order.server.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAttribute {
}

2.

package com.g2.order.server.annotation;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MaskLogAttribute {
    /**
     * 正则表达式,匹配到的将被转换为 ****
     * @return
     */
    String value() default "";
}

 

3.新建切面

package com.g2.order.server.aspect;

import com.g2.order.server.annotation.LogAttribute;
import com.g2.order.server.annotation.MaskLogAttribute;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springside.modules.utils.text.JsonMapper;

import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//开启AspectJ 自动代理模式,如果不填proxyTargetClass=true,默认为false,
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Component
@Aspect
@Order(100)
public class AnnotationLogAspectConfig {
    private static Logger logger = LoggerFactory.getLogger(AnnotationLogAspectConfig.class);

    @Pointcut("@annotation(com.g2.order.server.annotation.LogAttribute)")
    public void logPointcut() {

    }

    @Pointcut("@annotation(com.g2.order.server.annotation.MaskLogAttribute)")
    public void maskLogPointcut() {

    }

    @Around("maskLogPointcut() || logPointcut()")
    public Object handleControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("进入日志切面");

        //获取controller对应的方法.
        org.aspectj.lang.reflect.MethodSignature methodSignature = (org.aspectj.lang.reflect.MethodSignature) proceedingJoinPoint.getSignature();
        //获取方法所在的类(controller)
        Class beanType = methodSignature.getDeclaringType();
        //获取方法
        Method method = methodSignature.getMethod();

        String input, output;

        //获取方法参数列表(无需处理讨厌的流了)
        Object[] args = proceedingJoinPoint.getArgs();
        if (args.length == 0) {
            input = "(null)";
        } else {
            input = JsonMapper.INSTANCE.toJson(args[0]);
        }

        Object obj = proceedingJoinPoint.proceed();
        //获取返回值的类型,与 Method.getReturnType()一致
        output = JsonMapper.INSTANCE.toJson(obj);
        if (method.isAnnotationPresent(MaskLogAttribute.class)) {
            MaskLogAttribute maskLogAttribute = method.getAnnotation(MaskLogAttribute.class);
            String expr = maskLogAttribute.value();
            Pattern exprPattern = Pattern.compile(expr);
            Matcher m = exprPattern.matcher(input);
            input = m.replaceAll("****");
            m = exprPattern.matcher(output);
            output = m.replaceAll("****");
        }

        logger.info("类{}的方法{}的 输入参数为:{},输出参数为:{}", method.getDeclaringClass().getCanonicalName(), method.getName(),
                input, output);
        return obj;
    }
}

 

5.controller类

package com.g2.order.server.controller;

import com.g2.order.dao.mapper.user.UserMapper;
import com.g2.order.server.annotation.MaskLogAttribute;
import com.g2.order.server.vo.user.UserLoginReq;
import com.g2.order.dao.model.user.UserDao;
import com.g2.order.server.vo.user.UserLoginResp;
import com.g2.order.server.vo.user.UserModel;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

@Api(value = "HomeController", description = "用户登录登出接口")
@RestController
@RequestMapping("/home")
public class HomeController {
    private static Logger logger = LoggerFactory.getLogger(HomeController.class);
    @Autowired
    private UserMapper userMapper;

    @ApiOperation(value = "用户登录", notes = "用户登录接口")
    @RequestMapping(value = "/login",
            method = RequestMethod.POST,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @MaskLogAttribute("\\d{3}")
    public UserLoginResp login(@RequestBody UserLoginReq req) {
        logger.info("进入登陆业务");
        UserDao userDao = userMapper.getById(1);
        UserModel userModel = new UserModel();
        userModel.setRoleId(123);
        userModel.setUserId(Integer.toString(userDao.getUserId()));
        return new UserLoginResp(userModel);
    }
}

 

6.启动springboot

package com.g2.order.server;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
 * 程序入口
 */
@SpringBootApplication
@ServletComponentScan
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

 

7.调用

 

http://127.0.0.1:88/home/login

Post

{
    "userId":"123","password":"123444"
}

8.输出

2018-09-26 09:25:55.047  INFO 16716 --- [p-nio-88-exec-1] c.g.o.s.a.AnnotationLogAspectConfig      : 类com.g2.order.server.controller.HomeController的方法login的 输入参数为:{"corId":null,"userId":"****","password":"********"},输出参数为:{"success":true,"errorMessage":"","payload":{"userId":"1","roleName":null,"roleId":****}}

 

posted @ 2018-09-26 09:54  zslm___  阅读(2003)  评论(0编辑  收藏  举报