JAva webログ記録のspring aop実現方式

4731 ワード

実装構想: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;
	}