枚舉類:
/** * 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方法解析參數;