1. 程式人生 > >spring AOP的@Around輸出請求引數和返回引數

spring AOP的@Around輸出請求引數和返回引數

spring 的AOP是通過cglib動態代理和jdk的動態代理實現的。

先把我的列印日誌程式碼貼出來

package com.zhd.exploit.api.config;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletResponseWrapper;

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.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder;

import com.alibaba.fastjson.JSONObject;

@Aspect
@Component
@Order(1)
public class ControllerLogInterceptor {
	private static final Logger log = LoggerFactory.getLogger(ControllerLogInterceptor.class);
    //建立Pointcut表示式,表示所有controller請求
	@Pointcut("execution(* com..*.controller..*(..))")
	private void controllerAspect() {
	}// 請求method前列印內容

	@Around(value = "controllerAspect()")
	public void around(ProceedingJoinPoint pjp) throws Throwable {
	//通過uuid關聯請求引數和返回引數
		String uuid = UUID.randomUUID().toString().replaceAll("-", "");
		methodBefore(pjp, uuid);
		try {
			Object proceed = pjp.proceed();
			methodAfterReturing(proceed, uuid);
		} catch (Exception e) {
			log.error("[{}]Response異常內容:{}", uuid, e);
			throw e;
		}
	}

	public void methodBefore(JoinPoint joinPoint, String uuid) {
		// 列印請求內容
		try {
			// 下面兩個陣列中,引數值和引數名的個數和位置是一一對應的。
			Object[] objs = joinPoint.getArgs();
			String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); // 引數名
			Map<String, Object> paramMap = new HashMap<String, Object>();
			for (int i = 0; i < objs.length; i++) {
				if (!(objs[i] instanceof ExtendedServletRequestDataBinder) && !(objs[i] instanceof HttpServletResponseWrapper)) {
					paramMap.put(argNames[i], objs[i]);
				}
			}
			if (paramMap.size() > 0) {
				log.info("\n[{}]方法:{}\n引數:{}", uuid, joinPoint.getSignature(), JSONObject.toJSONString(paramMap));
			}
		} catch (Exception e) {
			log.error("[{}]AOP methodBefore:", uuid, e);
		}
	}

	public void methodAfterReturing(Object o, String uuid) {
		try {
			if (o != null)
				log.info("[{}]Response內容:{}", uuid, JSONObject.toJSON(o));
		} catch (Exception e) {
			log.error("[{}]AOP methodAfterReturing:", uuid, e);
		}
	}
}

測試

請求引數型別1

	@RequestMapping(value = "/test0", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
	public Result test0(@RequestParam String name, @RequestParam String password) {
		System.out.println("test0 OK");
		return new Result("1", "mock a Result");

	}

列印日誌:

[fe7155a3089b4dd7896b759a933cf958]方法:Result com.zhd.exploit.api.controller.TestController.test0(String,String)
引數:{"password":"123","name":"zhang"}

請求引數型別2

	@RequestMapping(value = "/test1", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
	public Result test1(PayDTO payDTO) {
		System.out.println("test1 OK");
		return new Result("1", "mock a Result");

	}

列印日誌:

[a2f7d19dea834c54a45b480bd4e8c3cd]方法:Result com.zhd.exploit.api.controller.TestController.test1(PayDTO)
引數:{"payDTO":{"appmount":"10","paytype":"1"}}

請求引數型別3

	@RequestMapping(value = "/test2", method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE })
	public Result test2(@RequestBody PayDTO payDTO) {
		System.out.println("test2 OK");
		return new Result("2", "mock a Result");

	}

列印日誌:

[cd6a3d9d05244eee95bbf3c607d038cc]方法:Result com.zhd.exploit.api.controller.TestController.test2(PayDTO)
引數:{"payDTO":{"appmount":"10","paytype":"1"}}