Reputation: 1520
I have created an aspect to log the request body passed in a controller function:
This is what i am trying
@Pointcut("execution(* com.test.test.test.controller.*.* (..))")
public void executeController() {}
@Pointcut("execution(* com.test.test.common.exception.*.* (..))")
public void executeExceptionAdvice() {}
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || "
+ "@annotation(org.springframework.web.bind.annotation.PostMapping) || "
+ "@annotation(org.springframework.web.bind.annotation.PutMapping) ||"
+ "@annotation(org.springframework.web.bind.annotation.ExceptionHandler)")
public void logRequestMapping() {}
@Before("logRequestMapping() && executeController() && args(..,@RequestBody requestBody) ")
public void logRequestBody(JoinPoint joinPoint, Object requestBody) {
LOGGER = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
LOGGER.info("Method : {},Request Body:{}",
LOGGER.getName() + "." + joinPoint.getSignature().getName(),
MaskingUtil.jsonifyAndMask(requestBody));
}
Now instead of matching with @RequestBody spring is matching arguments with .. i.e. generalize arguments and logging everything which is passed instead of the request body.I want to log only request body and if it is null the it won't print anything.
Upvotes: 0
Views: 9800
Reputation: 67297
You already found my related answer, but I just noticed the link in the comment under the wrong answer here after preparing an example for you. BTW, I used pure POJO + AspectJ, not Spring AOP (only Spring libs on the classpath so as to be able to resolve the annotations), but the aspect should be the same there.
P.S.: My example is better suited to your problem because the pointcut here specifically matches target methods bearing the @RequestBody
annotation. In the other example you would have to match all methods and then filter during runtime.
Dummy target classes:
I use two classes to test both of your package names. Otherwise they are the same.
package com.test.test.test.controller;
import org.springframework.web.bind.annotation.*;
public class MyController {
// These should trigger the aspect
@RequestMapping public String one(int number, @RequestBody String name) { return "Hey!"; }
@PostMapping public void two(int number, @RequestBody String name) {}
@PutMapping public String three(@RequestBody String name) { return "Ho!"; }
@ExceptionHandler public void four(@RequestBody String name) {}
// These should *not* trigger the aspect
public String noAnnotation(@RequestBody String name) { return "No annotation"; }
public String alsoNoAnnotation(String name) { return "Also no annotation"; }
@RequestMapping public String five(int number, String name) { return "foo"; }
@PostMapping public void six(int number, String name) {}
@PutMapping public String seven(String name) { return "bar"; }
@ExceptionHandler public void eight(String name) {}
}
package com.test.test.common.exception;
import org.springframework.web.bind.annotation.*;
public class MyExceptionHandler {
// These should trigger the aspect
@RequestMapping public String one(int number, @RequestBody String name) { return "Hey!"; }
@PostMapping public void two(int number, @RequestBody String name) {}
@PutMapping public String three(@RequestBody String name) { return "Ho!"; }
@ExceptionHandler public void four(@RequestBody String name) {}
// These should *not* trigger the aspect
public String noAnnotation(@RequestBody String name) { return "No annotation"; }
public String alsoNoAnnotation(String name) { return "Also no annotation"; }
@RequestMapping public String five(int number, String name) { return "foo"; }
@PostMapping public void six(int number, String name) {}
@PutMapping public String seven(String name) { return "bar"; }
@ExceptionHandler public void eight(String name) {}
}
Driver application:
package de.scrum_master.app;
import com.test.test.common.exception.MyExceptionHandler;
import com.test.test.test.controller.MyController;
public class Application {
public static void main(String[] args) {
MyController controller = new MyController();
// These should trigger the aspect
controller.one(1, "one");
controller.two(2, "two");
controller.three("three");
controller.four("four");
// These should *not* trigger the aspect
controller.noAnnotation("none");
controller.five(1, "five");
controller.six(2, "six");
controller.seven("seven");
controller.eight("eight");
controller.alsoNoAnnotation("none either");
MyExceptionHandler handler = new MyExceptionHandler();
// These should trigger the aspect
handler.one(1, "one");
handler.two(2, "two");
handler.three("three");
handler.four("four");
// These should *not* trigger the aspect
handler.noAnnotation("none");
handler.five(1, "five");
handler.six(2, "six");
handler.seven("seven");
handler.eight("eight");
handler.alsoNoAnnotation("none either");
}
}
Aspect:
package de.scrum_master.aspect;
import java.lang.annotation.Annotation;
import org.aspectj.lang.JoinPoint;
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.springframework.web.bind.annotation.RequestBody;
@Aspect
public class MyAspect {
@Pointcut("execution(* com.test.test.test.controller..*(.., @org.springframework.web.bind.annotation.RequestBody (*), ..))")
public void executeController() {}
@Pointcut("execution(* com.test.test.common.exception..*(.., @org.springframework.web.bind.annotation.RequestBody (*), ..))")
public void executeExceptionAdvice() {}
@Pointcut(
"@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
"@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
"@annotation(org.springframework.web.bind.annotation.PutMapping) ||" +
"@annotation(org.springframework.web.bind.annotation.ExceptionHandler)"
)
public void logRequestMapping() {}
@Before(
"logRequestMapping() &&" +
"(executeController() || executeExceptionAdvice())"
)
public void logRequestBody(JoinPoint thisJoinPoint) {
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
Annotation[][] annotationMatrix = methodSignature.getMethod().getParameterAnnotations();
int index = -1;
for (Annotation[] annotations : annotationMatrix) {
index++;
for (Annotation annotation : annotations) {
if (!(annotation instanceof RequestBody))
continue;
Object requestBody = thisJoinPoint.getArgs()[index];
System.out.println(thisJoinPoint);
System.out.println(" Request body = " + requestBody);
}
}
}
}
Console log:
execution(String com.test.test.test.controller.MyController.one(int, String))
Request body = one
execution(void com.test.test.test.controller.MyController.two(int, String))
Request body = two
execution(String com.test.test.test.controller.MyController.three(String))
Request body = three
execution(void com.test.test.test.controller.MyController.four(String))
Request body = four
execution(String com.test.test.common.exception.MyExceptionHandler.one(int, String))
Request body = one
execution(void com.test.test.common.exception.MyExceptionHandler.two(int, String))
Request body = two
execution(String com.test.test.common.exception.MyExceptionHandler.three(String))
Request body = three
execution(void com.test.test.common.exception.MyExceptionHandler.four(String))
Request body = four
Upvotes: 2
Reputation: 3805
Maybe you should write the full path of @RequestBody :
@annotation(org.springframework...RequestBody) requestBody
Upvotes: 0