java 注解结合spring AOP实现控制层API请求日志管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29777207/article/details/85732050

1、定义java 注解

package com.video.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
	
	public String desc() default "";

}

2、利用Spring AOP 实现日志管理

package com.video.annotation;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONObject;
import com.video.utils.JsonUtils;


@Aspect
@Component
public class RequestLog {
	
	private static final Logger logger = LoggerFactory.getLogger(RequestLog.class);
	
	/**
	 * 定义一个切点
	 */
	//@Pointcut("execution( * com.video.annotation.*.*(..))")
	@Pointcut("@annotation(com.video.annotation.SystemLog)")
	public void controllerLog() {}
	
	

	/**
	 * 在调用前打印日志
	 * @param joinPoint
	 * @throws Exception
	 */
	@Before("controllerLog()")
	public void before(JoinPoint joinPoint) throws Exception {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		
		logger.info("请求的IP:{}",request.getRemoteAddr());
		
		logger.info("请求的路径:{}",request.getRequestURI());
		
		logger.info("请求的方式:{}",request.getMethod());
		
		logger.info("方法描述:{}",getMethodDescription(joinPoint));
		
		logger.info("请求的参数:{}",JSONObject.toJSONString(request.getParameterMap()));
	}
	
	/**
	 * 获取注解目标方法的说明
	 * @param joinPoint
	 * @return
	 * @throws Exception
	 */
	private String getMethodDescription(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.getDeclaredMethods();
		
		String description = "";
		
		for(Method method : methods) {
			if(method.getName().equals(methodName)) {
				Class<?>[] classz = method.getParameterTypes();
				if(classz.length == arguments.length) {
					description = method.getAnnotation(SystemLog.class).desc();
					break;
				}
			}
		}
		
		return description;
	}
	
	/**
	 * 打印请求方法执行花费的时间和返回值
	 * @param joinPoint
	 * @return
	 * @throws Throwable
	 */
	@Around("controllerLog()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		long startTime = System.currentTimeMillis();
		
		Object[] arguments = joinPoint.getArgs();
		
		Object retVal = joinPoint.proceed(arguments);
		
		long endTime = System.currentTimeMillis();
		
		logger.info("执行时间:{} ms",endTime - startTime);
		
		logger.info("返回值:{} \n\t",JsonUtils.obj2Json(retVal));
		
		return retVal;
		
	}
	
	/**
	 * 打印异常
	 * @param e
	 * @throws Exception
	 */
	@AfterThrowing("controllerLog()")
	public void afterThrowing(Throwable e) throws Exception {
		logger.info("发生异常:{}",e.toString());
	}
	
}

3、定义JSON转换工具类(利用com.fasterxml.jackson)

package com.video.utils;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.LinkedHashMap;
import java.util.Map;

public class JsonUtils {

	private static JsonFactory jsonFactory = new JsonFactory();
	private static ObjectMapper objectMapper = new ObjectMapper();
	static {
		objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
		objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
		objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
	}

	/**
	 * object 转 json 串,异常时返回空串
	 * 
	 * @param obj
	 * @return
	 */
	public static String obj2Json(Object obj) {
		String json = null;
		try {
			json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return json;
	}

	/**
	 * json串 转 object ,异常时返回 null
	 * 
	 * @param json
	 * @param clazz
	 * @return
	 */
	public static <T> T json2Obj(String json, Class<T> clazz) {
		try {
			return objectMapper.readValue(json, clazz);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * json串 转 Map, 异常时返回空Map
	 * 
	 * @param json
	 * @return
	 */
	public static Map<String, Object> json2Map(String json) {
		try {
			TypeReference<LinkedHashMap<String, Object>> typeRef = new TypeReference<LinkedHashMap<String, Object>>() {
			};
			return objectMapper.readValue(json, typeRef);
		} catch (Exception e) {
		}
		return new LinkedHashMap<String, Object>();
	}
	
}

4、控制层接口加上自定义注解

        @SystemLog(desc="获取视频列表")
	@RequestMapping(value="/getVideoList.do",method= {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public TableResult getVideoList(int limit,int page,String channelType) throws Exception
	{
		TableResult resultMap = new TableResult();
		List<Video> list = new ArrayList<Video>();
		try {
			if(ValidateUtil.isNotEmpty(channelType)) {
				list = videoService.selectChanelType(limit, (page-1)*limit, channelType);
			}else {
				list = videoService.getAll(limit,(page-1)*limit);
			}
	        resultMap.setCode(0);  
	        resultMap.setCount(videoService.countVideo());
	        resultMap.setMsg("获取数据成功");
	        resultMap.setData(list);
	        System.out.println("获取数据成功");
		}catch(Exception e) {
			resultMap.setCode(500);  
	        resultMap.setCount(0);
	        resultMap.setMsg("获取数据失败");
	        resultMap.setData(null);
	        System.out.println("获取数据失败");
	        e.printStackTrace();
		}
		return resultMap;	
	}

猜你喜欢

转载自blog.csdn.net/qq_29777207/article/details/85732050