Как записать тело запроса в журнал с помощью Spring Boot и Aspect

Я создал аспект для регистрации тела запроса, переданного в функции контроллера:

Это то, что я пытаюсь

@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));
  }

Теперь вместо сопоставления с @RequestBody spring сопоставляет аргументы с .., то есть обобщает аргументы и регистрирует все, что передается вместо тела запроса. Я хочу регистрировать только тело запроса, и если оно равно нулю, он ничего не печатает.

Было бы неплохо, если бы даже по прошествии такого длительного времени вы решили оставить отзыв и принять и проголосовать за мой ответ, если он уместен. Я думаю, что это. После этого я могу снова удалить этот комментарий. Нехорошо задавать вопросы, а затем игнорировать ответы после того, как кто-то приложил много усилий, чтобы подготовить для вас исчерпывающий образец.

kriegaex 18.04.2020 05:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
5 032
2

Ответы 2

Возможно, вам стоит написать полный путь к @RequestBody:

@annotation(org.springframework...RequestBody) requestBody

Нет успеха при использовании этого

Atul Agrawal 23.05.2018 13:17

В итоге получил вот такое: - stackoverflow.com/questions/27659523/…

Atul Agrawal 23.05.2018 14:35

Вы уже нашли мой связанный ответ, но я только что заметил ссылку в комментарии под неправильным ответом здесь после того, как подготовил для вас пример. Кстати, я использовал чистый POJO + AspectJ, а не Spring AOP (только библиотеки Spring в пути к классам, чтобы иметь возможность разрешать аннотации), но аспект должен быть таким же.

P.S .: Мой пример лучше подходит для вашей проблемы, потому что pointcut здесь специально соответствует целевым методам с аннотацией @RequestBody. В другом примере вам нужно будет сопоставить все методы, а затем выполнить фильтрацию во время выполнения.

Классы фиктивных целей:

Я использую два класса для проверки обоих имен ваших пакетов. В остальном они такие же.

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) {}
}

Приложение драйвера:

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");
  }
}

Аспект:

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);
      }
    }
  }
}

Журнал консоли:

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

Я использую совет контроллера, и аспект не работает для @ExceptionHandler.

Kiran Kumar 19.08.2020 05:39

Пожалуйста, будьте так любезны и задайте новый вопрос вместо того, чтобы угонять этот. Пожалуйста, также объясните больше и покажите MCVE в своем будущем вопросе. Вы не можете ожидать, что я волшебным образом «отлажу» одно предложение прозы.

kriegaex 19.08.2020 06:46

Другие вопросы по теме