Reputation: 1811
Here is my problem :
I have an annotation :
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DummyAnnotation {
String dummyParam1();
String dummyParam2();
}
My service is :
@Component
public class DummyService {
@DummyAnnotation(dummyParam1="#otp",dummyParam2="#transactionId")
public void dummy(String otp, String transactionId){
}
}
My aspect is trying to validate the two arguments and throw exception if the validation don't successed :
@Around(value = "@annotation(annotation)")
public Object verifyOtp(final ProceedingJoinPoint jointPoint, final DummyAnnotation annotation) throws Throwable {
String transactionId = annotation.dummyParam1();
String otp = annotation.dummyParam2();
Boolean otpValid = otpService.verify(transactionId, otp);
if (otpValid) {
return jointPoint.proceed();
}
else {
throw new AuthentificationForteException();
}
}
How can i get this working because Spring EL is not working and in my Aspect i have dummyAnnotation.dummyParam1() Equal to "#otp" and not to the value of my argument String otp .
Thanks in advance .
Upvotes: 1
Views: 3564
Reputation: 1811
Finnaly i find a solution :
The solution is to implement a specific Spring Expression Parser.
I added these declaration to my aspect :
private ExpressionParser expressionParser = new SpelExpressionParser();
private ParserContext parserContext = new TemplateParserContext();
and I changed how I retrieved my dummyValue :
@Around(value = "@annotation(annotation)")
public Object verifyOtp(final ProceedingJoinPoint jointPoint, final DummyAnnotation annotation) throws Throwable {
String transactionId = getDummyValue(annotation.dummyParam1(),jointPoint.getArgs());
String otp = getDummyValue(annotation.dummyParam2(),jointPoint.getArgs());
Boolean otpValid = otpService.verify(transactionId, otp);
if (otpValid) {
return jointPoint.proceed();
}
else {
throw new AuthentificationForteException();
}
}
getDummyValue is a method that parse the expression :
private String getDummyValue(String authExpression, Object[] args){
Expression expression = expressionParser.parseExpression(authExpression, parserContext);
String value = expression.getValue(new RootObject(args),String.class);
return value;
}
private static class TemplateparserContext implements ParserContext{
@Override
public boolean isTemplate() {
return true;
}
@Override
public String getExpressionPrefix() {
return "#{";
}
@Override
public String getExpressionSuffix() {
return "}";
}
}
protected static class RootObject {
private final Object[] args;
private RootObject(Object[] args) {
super();
this.args = args;
}
public Object[] getArgs() {
return args;
}
}
and finally I changde my service and the use of the DummyAnnotation to :
@Component
public class DummyService {
@DummyAnnotation(dummyParam1="#{args[0]}",dummyParam2="#{args[1]}")
public void dummy(String otp, String transactionId){
}
}
Upvotes: 2
Reputation: 11353
Wouldn't writing an aspect that works against this be simpler?
@DummyAnnotation
public void dummy(@Otp String otp, @TransactionId String transactionId){
...
}
It would also not be Spring-specific, making it easier to test.
(If you intend to traverse into the arguments to extract the OTP or TX ID, e.g. #foo.txId, then this won't work of course, but I think it's simpler otherwise.)
Upvotes: 1