java web日誌記錄之spring aop實現方式

實現思路:spring aop切入到bean,在需要寫日誌的方法加入註解AuditLog,如果沒有註解的方法則不記錄日誌。

註解類

@Target({ElementType.PARAMETER, ElementType.METHOD})    
@Retention(RetentionPolicy.RUNTIME)    
@Documented 
public @interface AuditLog {
	 String description()  default "";//操作內容
	 StoreLogType logType() default StoreLogType.All;//操作類型
}

spring aop切入類

@Aspect
@Component
public class StoreLogCut {
	private static final Logger logger = LoggerFactory.getLogger(StoreLogCut.class);
	
	private static final String storeLogJsonParams = "storeLogJsonParams";//切入Controller請求參數爲json類型需要將請求對象賦予該名稱的屬性,以便獲取請求參數

	private StoreLogService storeLogService;

	/**
	 * Controller層切入點
	 */
	@Pointcut("execution(public * com.cd.store.controller.*.*(..))")
	public void controllerAspect() {
	}

	/**
	 * 後置返回通知
	 * 
	 * @param joinpoint
	 * @param returnValue
	 * @throws Throwable
	 */
	@AfterReturning(value = "controllerAspect()", returning = "returnValue")
	public void after(JoinPoint joinpoint, Object returnValue) throws Throwable {
		writeLog(joinpoint, returnValue);
	}

	/**
	 * 異常返回通知
	 * 
	 * @param joinpoint
	 * @param errorMsg
	 */
	@AfterThrowing(value = "controllerAspect()", throwing = "errorMsg")
	public void afterThrowException(JoinPoint joinpoint, Exception errorMsg) {
		writeLog(joinpoint, errorMsg);
	}

	/**
	 * 記錄日誌
	 * 
	 * @param joinpoint
	 * @param obj
	 */
	private void writeLog(JoinPoint joinpoint, Object obj) {
		try {
			HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
					.getRequest();
			StoreLogDescDto storeLogDescDto = getControllerMethodDescription(joinpoint);
			String action = storeLogDescDto.getAction();
			// 如果加了日誌註解類則寫入日誌到數據庫
			if (StringUtils.isNotBlank(action)) {
				int result = StoreLogResultType.success.getType();
				String returnMsg = "";
				if (obj instanceof Exception) {// 異常通知
					result = StoreLogResultType.Error.getType();
					returnMsg = ((Exception) obj).getMessage();
				} else {// 正常返回通知
					returnMsg = String.valueOf(obj);
					// 解析返回的數據(如返回false則爲失敗)
					result = getProcessResult(returnMsg);
				}
				String userName = getUserName(request);// 獲取操作人
				String ip = Utils.getRequestIp(request);// 獲取客戶端ip地址
				String param = Utils.getParam(request,joinpoint,storeLogJsonParams);// 獲取請求參數
				String requestUrl = String.valueOf(request.getRequestURL());
				storeLogService.insertLog(userName, ip, param, action, storeLogDescDto.getType(), result, returnMsg,requestUrl);
			}
		} catch (Exception e) {
			String errorMsg = new StringBuilder().append("write log to database error,").append(e.getMessage())
					.toString();
			logger.error(errorMsg);
		}
	}

	private int getProcessResult(String returnMsg) {
		if (StringUtils.isNotBlank(returnMsg) && "false".equalsIgnoreCase(returnMsg)) {
			return StoreLogResultType.Error.getType();
		}
		return StoreLogResultType.success.getType();
	}

	/**
	 * 獲取用戶名
	 * 
	 * @param request
	 * @return
	 */
	private String getUserName(HttpServletRequest request) {
		HttpSession session = request.getSession();
		Object userNameObj = session.getAttribute(Constants.SS_ACCOUNT);
		String userName = "";
		if (userNameObj != null) {
			userName = (String) userNameObj;
		}
		return userName;
	}

	/**
	 * 獲取註解中對方法的描述信息 用於Controller層註解
	 * 
	 * @param joinPoint
	 *            切點
	 * @return 方法描述
	 * @throws Exception
	 */
	private StoreLogDescDto getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		StoreLogDescDto storeLogDescDto = new StoreLogDescDto();
		String description = "";
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					AuditLog storeLogAnnotation = method.getAnnotation(AuditLog.class);
					if (storeLogAnnotation != null) {
						description = storeLogAnnotation.description();
						int type = storeLogAnnotation.logType().getType();
						storeLogDescDto.setAction(description);
						storeLogDescDto.setType(type);
						break;
					}
				}
			}
		}
		return storeLogDescDto;
	}

	public StoreLogService getStoreLogService() {
		return storeLogService;
	}

	@Autowired
	@Required
	public void setStoreLogService(StoreLogService storeLogService) {
		this.storeLogService = storeLogService;
	}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章