spring-aop

AspectJ支持5种类型的通知注解

@Before:前置通知,在方法执行之前执行

@After:后置通知,在方法执行之后执行

@AfterRunning:返回通知,在方法返回结果之后执行

@AfterThrowing:异常通知,在方法抛出异常之后执行

@Around:环绕通知,围绕着方法执行 (可以不声明,若果声明返回值要用Object,否则返回为空,可以改变返回值慎用)

单切面中各通知方法执行顺序

Around->Before->切入点method->Around->After->afterReturning/afterThrowing

环绕前置----普通前置----环绕返回/异常----环绕后置----普通后置----普通返回/异常

 

HttpServletRequest常用获取URL的方法

request.getRequestURL()

返回完整的url,包括Http协议,端口号,servlet名字和映射路径,但它不包含请求参数

String getRequestURI():获取请求URI,等于项目名+Servlet路径:/Example/AServle

HttpServletRequest常用获取URL的方法_gris0509的博客-CSDN博客_request获取请求url

写切面

  1. 自定义注解类

定义注解格式:

public @interface 注解名 {定义体}

注解参数的可支持数据类型:

1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)

2.String类型

3.Class类型

4.enum类型

5.Annotation类型

6.以上所有类型的数组

元注解

@Target,说明了Annotation所修饰的对象范围 【属性,方法,类等】

@Retention,定义了该Annotation生命周期(编译/运行)

  1. SOURCE:在源文件中有效(即源文件保留)
  2. CLASS:在class文件中有效(即class保留) 默认策略
  3. RUNTIME:在运行时有效(即运行时保留)

@Documented注解是否将包含在JavaDoc中

@Inherited,是否允许子类继承该注解。

package com.sun.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
public @interface First {
    String value() default "";
    int num();
}

修改出参,给某些参数值加密

环绕切面,重写后必须有返回值,不能返回空

package com.csc.komodo.research.aop;

import com.baomidou.mybatisplus.plugins.Page;
import com.csc.komodo.research.common.Result;

import com.csc.komodo.research.utils.SM4Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author 
 * @date 
 * @description 加密敏感信息
 */
@Component
@Aspect
@Slf4j
public class SensitiveDataAspect {

    /**
     * 加密key
     */
    private static final String KEY = "research@csc";
    /**
     * 敏感参数集合
     */
    private static final List<String> RESPONSE_PARAMETER_LIST = new ArrayList<>();
    /**
     * 工号集合 内容以”csc“开头的,加密内容
     */
    private static final List<String> EMPLOYEE_ID_LIST = new ArrayList<>();
    /**
     * 员工编号
     */
    private static final String EMPLOYEE_ID_CONTENT_START = "CSC";

    static {
        RESPONSE_PARAMETER_LIST.add("mobilephone");
        RESPONSE_PARAMETER_LIST.add("phone");
        RESPONSE_PARAMETER_LIST.add("officeemail");
        RESPONSE_PARAMETER_LIST.add("email");

        EMPLOYEE_ID_LIST.add("id");
        EMPLOYEE_ID_LIST.add("objId");
        EMPLOYEE_ID_LIST.add("creatorId");
        EMPLOYEE_ID_LIST.add("employeeid");
        EMPLOYEE_ID_LIST.add("correspondingSellId");
        EMPLOYEE_ID_LIST.add("empId");
        EMPLOYEE_ID_LIST.add("employeeId");
    }

    /**
     * 拦截注解方法
     */
    @Pointcut("@annotation(com.csc.komodo.research.annotation.SensitiveData)")
    public void sensitiveDataPointCut() {
    }

    @AfterReturning(value = "sensitiveDataPointCut()", returning = "response")
    public void doSensitiveDataAfterReturning(JoinPoint joinPoint, Object response) {
        try {
            if (response instanceof Result) {
                Result result = (Result) response;
                Object object = result.getData();
                if (object instanceof Page) {
                    Page pageList = (Page) object;
                    Object records = pageList.getRecords();
                    if (records instanceof List) {
                        changListValue((List<Object>) records);
                    }
                } else if (object instanceof List) {
                    changListValue((List<Object>) object);
                } else if (object instanceof Map) {
                    changeMapValue(object, SM4Utils.ENCRYPT);
                } else if (object instanceof Object) {
                    changObjectValue(object, SM4Utils.ENCRYPT);
                }
            }
        } catch (Exception e) {
            log.error("SensitiveDataAspect-doSensitiveDataAfterReturning:", e);
        }
    }

    /**
     * @param objects
     * @throws IllegalAccessException
     */
    private void changListValue(List<Object> objects) throws IllegalAccessException {
        List<Object> list = objects;
        for (Object obj : list) {
            changObjectValue(obj, SM4Utils.ENCRYPT);
        }
    }


    /**
     * 修改Object对象field的值
     *
     * @param obj
     * @param flag
     * @return
     * @throws IllegalAccessException
     */
   private Object changObjectValue(Object obj, int flag) throws IllegalAccessException {
        Class<?> resultClz = obj.getClass();
        //获取class里的所有字段
        Field[] fieldInfo = resultClz.getDeclaredFields();
        for (Field field : fieldInfo) {
            //成员变量为private,必须进行此操作
            field.setAccessible(true);
            Object fieldValue = field.get(obj);
            Object fieldName = field.getName();
            if (RESPONSE_PARAMETER_LIST.contains(fieldName) && null != fieldValue) {
                String afterValue = crypto(fieldValue, flag);
                if (StringUtils.isNotEmpty(afterValue)) {
                    field.set(obj, afterValue);
                }
            }
            if (EMPLOYEE_ID_LIST.contains(fieldName) && null != fieldValue) {
                String id = String.valueOf(fieldValue);
                if (id.length() > 3) {
                    if (id.startsWith(EMPLOYEE_ID_CONTENT_START) || id.startsWith(EMPLOYEE_ID_CONTENT_START.toLowerCase())) {
                        String afterValue = crypto(fieldValue, flag);
                        if (StringUtils.isNotEmpty(afterValue)) {
                            field.set(obj, afterValue);
                        }
                    }
                }
            }
            long parameterNum = RESPONSE_PARAMETER_LIST.stream().filter(x -> String.valueOf(fieldValue).contains(x)).count();
            long idNum = EMPLOYEE_ID_LIST.stream().filter(x -> String.valueOf(fieldValue).contains(x)).count();
            if (parameterNum + idNum > 0) {
                if (field.get(obj) instanceof List) {
                    changListValue((List<Object>) field.get(obj));
                } else if (field.get(obj) instanceof List) {
                    changListValue((List<Object>) field.get(obj));
                } else if (field.get(obj) instanceof Map) {
                    changeMapValue(field.get(obj), SM4Utils.ENCRYPT);
                } else if (field.get(obj) instanceof Object) {
                    changObjectValue(field.get(obj), SM4Utils.ENCRYPT);
                }
            }
        }
        return obj;
    }

    /**
     * 当对象为Map 修改key的值
     *
     * @param obj
     * @param flag
     * @return
     */
    private Object changeMapValue(Object obj, int flag) {
        Map<String, Object> map = (Map<String, Object>) obj;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (RESPONSE_PARAMETER_LIST.contains(entry.getKey()) && null != entry.getValue()) {
                Object fieldValue = map.get(entry.getKey());
                String afterValue = crypto(fieldValue, flag);
                if (StringUtils.isNotEmpty(afterValue)) {
                    map.put(entry.getKey(), afterValue);
                }
            }
            if (EMPLOYEE_ID_LIST.contains(entry.getKey()) && null != entry.getValue()) {
                String id = String.valueOf(entry.getValue());
                if (id.length() > 3) {
                    if (id.startsWith(EMPLOYEE_ID_CONTENT_START) || id.startsWith(EMPLOYEE_ID_CONTENT_START.toLowerCase())) {
                        String afterValue = crypto(id, flag);
                        if (StringUtils.isNotEmpty(afterValue)) {
                            map.put(entry.getKey(), afterValue);
                        }
                    }
                }
            }
        }
        return obj;
    }

    /**
     * 加密解密操作
     *
     * @param value
     * @param flag  1加密 0解密
     * @return
     */
    private String crypto(Object value, int flag) {
        String result = null;
        if (null == value) {
            return null;
        }
        try {
            if (SM4Utils.ENCRYPT == flag) {
                result = SM4Utils.encode(String.valueOf(value), KEY);
            }
            if (SM4Utils.DECRYPT == flag) {
                result = SM4Utils.decode(String.valueOf(value), KEY);
            }
        } catch (IOException e) {
            log.info("SensitiveDataAspect:加解密失败:{}" + e);
        }
        return result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

what_2018

你的鼓励是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值