Springboot Aop切面获取请求参数返回参数,请求ip请求方法类型,打印日志
Springboot AOP 提高代码开发效率前文:最近和前端调试接口,总是有时候发现**参数对应不上,出现或多或少的情况,**这时候你每次打印就很麻烦,我们可以采用AOP设计方法!这个工具类可以实现每次请求接口,获取必要参数,比如ip地址 方法名接口名 接口参数方便你定位问题还有一个特别重要的就是返回参数我们可以通过AOP 的 @AfterReturning注解实现查看接口返回参数内容这里友情提
Springboot AOP 提高代码开发效率
前文:最近和前端调试接口,总是有时候发现**参数对应不上,出现或多或少的情况,**这时候你每次打印就很麻烦,我们可以采用AOP设计方法!
这个工具类可以实现每次请求接口,获取必要参数,
比如ip地址 方法名 接口名 接口参数方便你定位问题
还有一个特别重要的就是返回参数
我们可以通过AOP 的 @AfterReturning注解实现查看接口
返回参数内容
这里友情提示:post 请求返回的是JSON格式 如果传fromDate格式,也就是
@RequeryParm
package io.sugo.cdp.upload.download.config.aop;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
@Aspect
@Component
public class AopLogAspect {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* execution 指定controller
* !execution 排查指定controller下的方法
*/
@Pointcut("(execution(* io.sugo.cdp.upload.download.controller.*.*(..)) && !execution(* io.sugo.cdp.upload.download.controller.CdpUploadController.upload(..)))")
public void aopLogAspect() {
}
@Before("aopLogAspect()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
logger.info("请求开始 : ====================================================================================");
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 记录下请求内容
logger.info("请求类型 :" + request.getMethod() + " " + "请求URL : " + request.getRequestURL());
logger.info("请求IP : " + request.getRemoteAddr());
logger.info("请求方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
// 只记录post方法 传json格式的数据
if ("POST".equals(request.getMethod())) {
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
//方法 1 请求的方法参数值 JSON 格式 null不显示
if (joinPoint.getArgs().length > 0) {
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
//请求参数类型判断过滤,防止JSON转换报错
if (args[i] instanceof HttpServletRequest || args[i] instanceof HttpServletResponse || args[i] instanceof MultipartFile) {
continue;
}
logger.info("请求参数名称 :" + paramNames[i] + ", 内容 :" + JSON.toJSONString(args[i]));
}
}
} else {
//请求的方法参数值 兼容fromDate格式和JSON格式
Object[] args = joinPoint.getArgs();
// 请求的方法参数名称 显示所有字段 值为null也显示该字段
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = u.getParameterNames(method);
if (args != null && paramNames != null) {
String params = "";
for (int i = 0; i < args.length; i++) {
//请求参数类型判断过滤,
if (args[i] instanceof HttpServletRequest || args[i] instanceof HttpServletResponse || args[i] instanceof MultipartFile) {
continue;
}
params += " " + paramNames[i] + ": " + args[i] + ",";
}
logger.info("请求参数 :" + params);
}
}
}
@AfterReturning(returning = "ret", pointcut = "aopLogAspect()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
logger.info("返回内容 : " + JSON.toJSONString(ret));
logger.info("请求结束 :====================================================================================");
}
}
<!--aop 切面 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.3</version>
</dependency>`
`
AOP概念
来让我们看一下上面的一个小故事和 AOP 到底有什么对应关系. 首先我们知道, 在 Spring AOP 中 join point 指代的是所有方法的执行点, 而 point cut 是一个描述信息, 它修饰的是 join point, 通过 point cut, 我们就可以确定哪些 join point 可以被织入 Advice. 对应到我们在上面举的例子, 我们可以做一个简单的类比, join point 就相当于 爪哇的小县城里的百姓 , point cut 就相当于 老王所做的指控, 即凶手是个男性, 身高约七尺五寸 , 而 advice 则是施加在符合老王所描述的嫌疑人的动作: 抓过来审问 . 为什么可以这样类比呢?
join point --> 爪哇的小县城里的百姓: 因为根据定义, join point 是所有可能被织入 advice 的候选的点, 在 Spring AOP中, 则可以认为所有方法执行点都是 join point. 而在我们上面的例子中, 命案发生在小县城中, 按理说在此县城中的所有人都有可能是嫌疑人。
point cut --> 男性, 身高约七尺五寸: 我们知道, 所有的方法(joint point) 都可以织入 advice, 但是我们并不希望在所有方法上都织入 advice, 而 pointcut 的作用就是提供一组规则来匹配joinpoint, 给满足规则的 joinpoint 添加 advice. 同理, 对于县令来说, 他再昏庸, 也知道不能把县城中的所有百姓都抓起来审问, 而是根据凶手是个男性, 身高约七尺五寸, 把符合条件的人抓起来. 在这里 凶手是个男性, 身高约七尺五寸 就是一个修饰谓语, 它限定了凶手的范围, 满足此修饰规则的百姓都是嫌疑人, 都需要抓起来审问。
advice --> 抓过来审问, advice 是一个动作, 即一段 Java 代码, 这段 Java 代码是作用于 point cut 所限定的那些 join point 上的. 同理, 对比到我们的例子中, 抓过来审问 这个动作就是对作用于那些满足 男性, 身高约七尺五寸 的爪哇的小县城里的百姓。
aspect: aspect 是 point cut 与 advice 的组合, 因此在这里我们就可以类比: “根据老王的线索, 凡是发现有身高七尺五寸的男性, 都要抓过来审问” 这一整个动作可以被认为是一个 aspect。
更多推荐
所有评论(0)