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;
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值