Spring AOP: Como ler o valor da variável de caminho do modelo de URI no aspecto?
Eu quero criar o aspecto Spring que definiria o parâmetro do método, anotado pela anotação personalizada, para uma instância de uma classe específica identificada por um ID do modelo URI. O nome da variável do caminho é o parâmetro da anotação. Muito parecido com o que Primavera@PathVariable
faz.
Portanto, esse método de controlador seria semelhante a:
@RestController
@RequestMapping("/testController")
public class TestController {
@RequestMapping(value = "/order/{orderId}/delete", method = RequestMethod.GET)
public ResponseEntity<?> doSomething(
@GetOrder("orderId") Order order) {
// do something with order
}
}
Em vez de clássico:
@RestController
@RequestMapping("/testController")
public class TestController {
@RequestMapping(value = "/order/{orderId}/delete", method = RequestMethod.GET)
public ResponseEntity<?> doSomething(
@PathVariable("orderId") Long orderId) {
Order order = orderRepository.findById(orderId);
// do something with order
}
}
Fonte da anotação:
// Annotation
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface GetOrder{
String value() default "";
}
Fonte do aspecto:
// Aspect controlled by the annotation
@Aspect
@Component
public class GetOrderAspect {
@Around( // Assume the setOrder method is called around controller method )
public Object setOrder(ProceedingJoinPoint jp) throws Throwable{
MethodSignature signature = (MethodSignature) jp.getSignature();
@SuppressWarnings("rawtypes")
Class[] types = signature.getParameterTypes();
Method method = signature.getMethod();
Annotation[][] annotations = method.getParameterAnnotations();
Object[] values = jp.getArgs();
for (int parameter = 0; parameter < types.length; parameter++) {
Annotation[] parameterAnnotations = annotations[parameter];
if (parameterAnnotations == null) continue;
for (Annotation annotation: parameterAnnotations) {
// Annotation is instance of @GetOrder
if (annotation instanceof GetOrder) {
String pathVariable = (GetOrder)annotation.value();
// How to read actual path variable value from URI template?
// In this example case {orderId} from /testController/order/{orderId}/delete
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder
.currentRequestAttributes()).getRequest();
????? // Now what?
}
} // for each annotation
} // for each parameter
return jp.proceed();
}
}
ATUALIZAÇÃO 04 / Abr / 2017:
Resposta dada porMike Wojtyna responde a pergunta -> assim é aceito.
Resposta dada porOrangeDog resolve o problema da perspectiva diferente com as ferramentas existentes do Spring sem arriscar problemas de implementação com novo aspecto. Se eu soubesse disso antes, essa pergunta não seria feita.
Obrigado!