Прочитать значение аннотации RequestMapping - PullRequest
0 голосов
/ 12 марта 2020

Чтобы иметь возможность делать статистику по конечной точке, я хочу иметь возможность получить значение аннотации @RequestMapping, параметризованную версию. В противном случае мой инструмент мониторинга будет рассматривать разные идентификаторы как разные URL:

@RequestMapping(value = "/customers/{customerId}/items/{itemId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<ItemDetailsDto> getItemById(
      @PathVariable(value = "customerId") int customerId
      @PathVariable(value = "itemId") int itemId)
      throws Exception
  {
    //do stuff

    //I want this to be "/customers/{customerId}/items/{itemId}"
    //,not "/customers/15988/items/85"
    String s = ????
  }

Как я могу получить /customers/{customerId}/items/{itemId} во время выполнения? Мой инструмент позволяет мне перехватывать методы и захватывать их параметры, поэтому я также мог отслеживать определенный метод c в среде Spring для отслеживания установки или получения чего-либо, например.

Ответы [ 2 ]

0 голосов
/ 13 марта 2020

Другим подходом будет

private static final String URI_GET_ITEM_BY_ID ="/customers/{customerId}/items/{itemId}";

@RequestMapping(value = URI_GET_ITEM_BY_ID, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<ItemDetailsDto> getItemById(
      @PathVariable(value = "customerId") int customerId
      @PathVariable(value = "itemId") int itemId)
      throws Exception
  {
    //do stuff

    // Use URI_GET_ITEM_BY_ID

  }

Обновление 1:

При условии, что контроллер помечен @RestController

@RestController
public class SampleController {

      @RequestMapping(value = "/customers/{customerId}/items/{itemId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<ItemDetailsDto> getItemById(
      @PathVariable(value = "customerId") int customerId
      @PathVariable(value = "itemId") int itemId)
      throws Exception
  {
    //do stuff

    //I want this to be "/customers/{customerId}/items/{itemId}"
    //,not "/customers/15988/items/85"
    String s = ????
  }

}

следующим Aspect может использоваться для получения пути URI без изменения методов контроллера.

@Aspect
@Component
public class RestControllerAspect {

    @Pointcut("@within(org.springframework.web.bind.annotation.RestController) && within(rg.boot.web.controller.*)")
    public void isRestController() {

    }

    @Before("isRestController()")
    public void handlePost(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        // controller method annotations of type @RequestMapping
        RequestMapping[] reqMappingAnnotations = method
                .getAnnotationsByType(org.springframework.web.bind.annotation.RequestMapping.class);
        for (RequestMapping annotation : reqMappingAnnotations) {
            System.out.println(annotation.toString());
            for(String val : annotation.value()) {
                System.out.println(val);
            }
        }

    }
}

Это вывело бы

@org.springframework.web.bind.annotation.RequestMapping(path=[], headers=[], method=[GET], name=, produces=[application/json], params=[], value=[/customers/{customerId}/items/{itemId}], consumes=[])
/customers/{customerId}/items/{itemId}

для запроса к URI: /customers/1234/items/5678

Обновление 2:

Другой способ - импортировать

import static org.springframework.web.servlet.HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE;
import org.springframework.web.context.request.RequestContextHolder;

и получить путь, используя следующий код

 RequestAttributes reqAttributes = RequestContextHolder.currentRequestAttributes(); 
 String s = reqAttributes.getAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, 0);

This адаптировано из моего ответа на другой вопрос.

0 голосов
/ 12 марта 2020

Вы можете использовать Java отражение, чтобы сделать это, вам просто нужно сделать так:

String s= this.getClass().getDeclaredMethod("getItemById", int.class, int.class).getAnnotation(RequestMapping.class).value();

Для getDeclaredMethod первый параметр - это имя метода, а остальные параметры - это типы параметров этого метода.

...