枚举类:
/** * Created by tzq on 2018/5/21. */ public enum MyAnnoEnum { SELECT("select","查询"), INSERT("insert","添加"), UPDATE("update","修改"), DELECT("delect","删除"); private MyAnnoEnum(String code, String name) { this.code = code; this.name = name; } public static String getNameByCode(String code) { for (MyAnnoEnum enm : MyAnnoEnum.values()) { if (enm.getCode() == code) { return enm.getName(); } } return null; } private String code; private String name; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
pom.xml
<!--aop--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
MyAnno类:自定义注解类
import cn.supercop.idss.enm.MyAnnoEnum; import java.lang.annotation.*; /** * 自定义注解类 * Created by tzq on 2018/5/19. */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyAnno { MyAnnoEnum value(); }
HtppHandlerMethodAspect : aop 类
import ch.qos.logback.core.net.SyslogOutputStream; import cn.supercop.idss.config.MyAnno; import cn.supercop.idss.domain.system.AuditLog; import cn.supercop.idss.enm.MyAnnoEnum; import cn.supercop.idss.service.AuditLogService; import com.alibaba.fastjson.JSON; import org.apache.commons.lang.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.*; @Aspect //定义一个切面 @Component public class HtppHandlerMethodAspect { private Logger log = LoggerFactory.getLogger(HtppHandlerMethodAspect.class); private static final String[] IGNORE_URI = {"api/login"};//放行集合不进行aop @Autowired private AuditLogService auditLogService; /** * 过滤指定url不aop * @return true or false */ public boolean filter_URL(){ // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); boolean flag = false; String url = request.getRequestURL().toString(); log.info(">>>: " + url); for (String s : IGNORE_URI) { if (url.contains(s)) { log.info("访问路径包含在放行集合中"); flag = true; break; } } return flag ; } /** * 所有的 controller 层进行aop扫描 * @param joinPoint * @throws Exception */ @Before("execution(* cn.supercop.idss.controller..*(..))") public void executioncontroller(JoinPoint joinPoint) throws Exception { System.out.println("****************************controller 开始****************************"); if(!filter_URL()){ analysis(joinPoint); } System.out.println("****************************controller 结束****************************"); } /** * 所有的mapper层进行aop扫描, * @param joinPoint * @throws Exception @Before("execution(* cn.supercop.idss.mapper..*(..)) ") public void executemapper(JoinPoint joinPoint) throws Exception { System.out.println("****************************mapper 开始****************************"); if(!"cn.supercop.idss.mapper.AuditLogMapper.insert".equals(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName())) analysis(joinPoint); System.out.println("****************************mapper 结束****************************"); } */ public void analysis(JoinPoint joinPoint) throws Exception { // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 记录下请求内容 System.out.println("URL : " + request.getRequestURL().toString());//请求路径 System.out.println("HTTP_METHOD : " + request.getMethod());//请求方法类型 System.out.println("IP : " + request.getRemoteAddr());// //aop 切点的方法 System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); System.out.println("ARGS : " + Arrays.toString(joinPoint.getArgs())); //获取目标方法的参数信息 Object[] obj = joinPoint.getArgs(); for (Object o : obj) { System.out.println(o); } Enumeration<String> enumeration = request.getParameterNames(); Map<String, String> parameterMap = new HashMap(); while (enumeration.hasMoreElements()) { String parameter = enumeration.nextElement(); parameterMap.put(parameter, request.getParameter(parameter)); } String str = JSON.toJSONString(parameterMap); if (obj.length > 0) { System.out.println("请求的参数信息为:" + str); } String action = "缺少类型";//动作 //取自定义注解 Method method=((MethodSignature)joinPoint.getSignature()).getMethod(); Method realMethod = joinPoint.getTarget().getClass().getDeclaredMethod(joinPoint.getSignature().getName(), method.getParameterTypes()); Annotation an = method.getAnnotation(MyAnno.class); if(an instanceof MyAnno){ MyAnno myAnno = (MyAnno) an; action = myAnno.value().getName(); System.out.println("value: " + myAnno.value().getName()); } //取用户名 Subject subject = SecurityUtils.getSubject(); String username = subject.getPrincipal().toString(); if(MyAnnoEnum.SELECT.getName() != action){ AuditLog auditLog = new AuditLog(); auditLog.setOccurredTime(new Date());//发生时间 auditLog.setAction(action);//动作 auditLog.setObjectName(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());//操作对像名称 auditLog.setDescription(str);//描述 auditLog.setSource(request.getRequestURL().toString());// '源头'; auditLog.setClientIp(this.getRemortIP(request));//客户端IP auditLog.setUserId(new Long(1));//用户ID auditLog.setUserType("内部");//用户类型 auditLog.setStatus((short) 1);//执行状态 auditLog.setCreatedBy(username);//创建人 auditLog.setModifiedBy(username);//创建人 auditLogService.addAuditLog(auditLog); } } public String getRemortIP(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_CLIENT_IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } }
主要注解的类:
如Controller:
/** * 查询蓝牙访问列表 */ @MyAnno(MyAnnoEnum.SELECT) @RequestMapping("/selectBluetoothAccess") @ResponseBody public Result<Object> selectBluetoothAccess(BluetoothAccess bluetoothAccess) {
如mapper or Dao :
public interface WifiAccessMapper { Long count(@Param("personId") String personId); //查询 @MyAnno(MyAnnoEnum.SELECT) List<WifiAccess> select (WifiAccess wifiAccess); }
总结:
自定义一个注解,注解引用一个枚举来约束注解后的值,定义来insert/update/select/deltet, 定义在dao层或者Controller层都可以实现,可根据业务需要实现,
在aop HtppHandlerMethodAspect类,根据execution表达式来切,在类中定义来一个常量数组,来过滤一些一个表达式中需要过滤的信息,analysis方法解析参数;