CDI-Interceptor: Get param from intercepted Method - java

I have a interface
#InterceptorBinding
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD, ElementType.TYPE })
public #interface LoggingInterceptorBinding {
}
and a class:
#LoggingInterceptorBinding
#Interceptor
public class LoggingInterceptor implements Serializable {
#AroundInvoke
public Object onMethodCall(InvocationContext context) throws Exception {
try {
System.out.println("Log before Method");
return context.proceed();
} finally {
System.out.println("Log after Method");
}
}
and a annotated method:
#LoggingInterceptorBinding
public void sayHello(String name)
Is it possible to get the parameter "name" from sayHello in the interceptors "onMethodCalls"-method?

The InvocationContext interface has a getParameters() method that
Returns the parameter values that will be passed to the method of the
target class. If setParameters() has been called, getParameters()
returns the values to which the parameters have been set.

Related

Custom annotation does not work in method

I created annotation to check permissions on the APIs. Annotation worked when placed in class or method. But when I use it for both class and method at the same time, the annotation placed on the method is ignored
Here is an example:
#RestController
#RequestMapping("/user")
#CustomAnnotation(permission="manageUser")
public class UserController {
#CustomAnnotation(permission="updateUser")
#PutMapping("/{id}")
public UserDto getUser(HttpServletRequest request) {
...
}
}
Now #CustomAnnotation(permission="updateUser") in the getUser() method will be ignored and only execute annation in class UserController
My custom code
#Target(value = {ElementType.METHOD, ElementType.TYPE})
#Retention(value = RetentionPolicy.RUNTIME)
#Inherited
#Documented
public #interface CustomAuthorize {
public String permission() default "";
public String attribute() default "";
}
#Aspect
#Component
public class CustomAnnotationAspect {
#Autowired
CustomAuthorizationImpl authBean;
#Pointcut("#annotation(customAuthorize) || #within(customAuthorize)")
public void pointcutForCustomAnnotation(CustomAuthorize customAuthorize) {
// Do nothing.
}
#Around("pointcutForCustomAnnotation(customAuthorize)")
public Object customAspect(ProceedingJoinPoint pjp, CustomAuthorize customAuthorize) throws Throwable {
if (Objects.isNull(customAuthorize)) {
System.out.println("Call from method");
// Check permission
return pjp.proceed();
}
System.out.println("Call from class");
ExpressionParser elParser = new SpelExpressionParser();
if (!customAuthorize.permission().isBlank()) {
// check permission
}
return pjp.proceed();
}
}

Spring method annotations null

I'am trying to get the methods that are using a custom annotation, but when i get the method, i can't get any annotation from it, every paramter that cites "annotation" is null.
My annotation:
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
String value() default "";
}
Class using annotation:
public interface Interface {
void doSomething();
}
#Repository
public class ImplementationClass implements Interface {
#Override
#MyAnnotation("some_value")
public void doSomething() {
}
}
Getting annotation:
#Configuration
public class MyAnnotationScanner implements ApplicationContextAware {
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
for (String beanName : applicationContext.getBeanNamesForAnnotation(Repository.class)) {
Object bean = applicationContext.getBean(beanName);
for (Method beanMethod : bean.getClass().getDeclaredMethods()) {
if (beanMethod.isAnnotationPresent(MyAnnotation.class))
// do something
}
}
}
}
I'm able to get the correct method, but when i check with intellij it has no annotations and the "isAnnotationPresent" method always returns false.
I found a solution in using the AnnotationUtils.findAnnotation() method.
Basically for every beanMethod, you get the annotation using the findAnnotation method.
var annotation = AnnotationUtils.findAnnotation(beanMethod, MyAnnotation.class);
I was using isAnnotationPresent method but it was always returning false. I have then used AnnotationUtils.findAnnotation(method, <Annotation.class>)
Here is how I am finding method that is using custom annotation:
for (String beanName : applicationContext.getBeanDefinitionNames()) {
Object bean = applicationContext.getBean(beanName);
Class<?> objClass = bean.getClass();
for (Method m : objClass.getDeclaredMethods()) {
Annotation a = AnnotationUtils.findAnnotation(m, <Annotation_NAME>.class);
if (a != null) {

#AroundInvoke does not work when attribute supplied

I have following classes.
#Inherited
#InterceptorBinding
#Retention(RUNTIME)
#Target({ TYPE, METHOD })
public #interface MyLogger {
public boolean skipParams() default true;
}
#MyLogger
#Interceptor
public class MyInterceptor {
#AroundInvoke
public Object logMethod(InvocationContext joinPoint) throws Exception {
// Some log statements here
}
}
public class MyClass {
#MyLogger()
void test1(){
// some code
}
#MyLogger(skipParams = true)
void test2(){
// some code
}
#MyLogger(skipParams = false)
void test3(){
// some code
}
}
#AroundInvoke does not work when attribute supplied.
logMethod() gets called for test1(), but not for test2() and test3().

pass result of annotation work to annotated method

Annotation:
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface Multipart {
Class acceptClass();
}
Annotated method:
#Multipart (acceptClass = SomeClass.class)
public void someMethod(SomeClass a){
//do stuff..
}
MultipartAspect:
#Aspect
public class MultipartAspect {
#Autowired(required=true)
private HttpServletRequest request;
#Pointcut(value = "#annotation(Multipart)", argNames = "multipart")
public void before(JoinPoint jp, Multipart multipart) {}
#Before("before()")
public SomeClass doStuffBeforeThing() {
SomeClass sc = new SomeClass(); //object of passed class
//do something..
return sc; //return this to annotated method(somemethod)
}
}
I want before method works execute annotation, create object of passed class(SomeClass) and the pass object of this class to annotated method. Could I do this?
You should use #Around advice instead of #Before.

How to get class level annotation from ProceedingJoinPoint

I am trying to implement an interceptor with #Aspect. I need to get class level annotation
Here is my interceptor
#Aspect
public class MyInterceptor {
#Around("execution(* com.test.example..*(..))")
public Object intercept(ProceedingJoinPoint pjp) throws Throwable {
Object result;
try {
result = pjp.proceed();
} catch (Throwable e) {
throw e;
}
return result;
}
}
and here is my annotation
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotation {
String reason();
}
and here is the class
#MyAnnotation(reason="yes")
public class SomeClassImpl implements SomeClass {
}
In interceptor I need to get the annotation and the value assigned to reason attribute.
Interceptor class to get value of the annotation marked at class level
#Aspect
#Component
public class MyInterceptor {
#Around("#target(annotation)")
public Object intercept(ProceedingJoinPoint joinPoint, MyAnnotation annotation) throws Throwable {
System.out.println(" called with '" + annotation.reason() + "'");
return joinPoint.proceed();
}
}

Categories

Resources