To be able to do stats per endpoint, I want to be able to get the @RequestMapping annotation value, the parameterized version. My monitoring tool otherwise will consider different ids as different urls:
@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 = ????
}
How can I grab /customers/{customerId}/items/{itemId}
at runtime? My tool allows me to intercept methods and capture its parameters, so I could also monitor a specific method in the Spring framework to catch the setting or getting of something for example.
You can use Java
reflection to do so, you just need to do like this:
String s= this.getClass().getDeclaredMethod("getItemById", int.class, int.class).getAnnotation(RequestMapping.class).value();
For the getDeclaredMethod
the first parameter is the name of method and the other parameters are the parameters' types of that method.
Another approach will be
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
}
Update 1:
Assuming the controller is annotated with @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 = ????
}
}
following Aspect
can be used to get the URI path without altering the controller methods.
@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);
}
}
}
}
This would print
@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}
for a request to URI : /customers/1234/items/5678
Update 2:
Another way is to import
import static org.springframework.web.servlet.HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE;
import org.springframework.web.context.request.RequestContextHolder;
and get the path using the following code
RequestAttributes reqAttributes = RequestContextHolder.currentRequestAttributes();
String s = reqAttributes.getAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, 0);
This is adapted from my answer to another question.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.