Speck
Speck

Reputation: 2299

Using a custom annotation on a Spring MVC controller method from an interceptor

I have a custom annotation with which I've annotated a method in my Controller alongside a @ReqestMapping.

The goal is to use the values set in the custom annotation from a HandlerInterceptor to perform a task.

I have the interceptor (HandlerInterceptorAdaptor) mapped and it executes. If I set a breakpoint in my concrete Interceptor I can inspect the HttpServletRequest, HttpServletResponse, and handler Objects. However, I cannot see how to 1, obtain the method which the request is trying to access 2, obtain the Annotations on that method and 3, of course, obtain the values set by the annotation.

Can anyone point me to good documentation for this?

Please and Thank You.

Upvotes: 5

Views: 6533

Answers (6)

NaN
NaN

Reputation: 9094

I was looking for the same solution and I found that tutorial https://saarthakvats.wordpress.com/2016/05/29/spring-4-mvc-request-interceptor-and-custom-method-argument-annotation-resolver/comment-page-1/#comment-9 where they create the handler and the annotation to deliver user id after the handler checked if the token was ok inside the end-point method. With just a little modification we can turn it into an annotation to determine if that end-point is a public one or needs an user role.

Another example that is closer to what we need: https://www.future-processing.pl/blog/exploring-spring-boot-and-spring-security-custom-token-based-authentication-of-rest-services-with-spring-security-and-pinch-of-spring-java-configuration-and-spring-integration-testing/

Upvotes: 0

Rossen
Rossen

Reputation: 111

in Spring 3.1 we've introduced a HandlerMethod abstraction to represent that specific controller method that will handle the request. There is HandlerMapping and a HandlerAdapter specifically for that. You can read about this in more detail in my blogpost following the M2 release.

https://spring.io/blog/2011/06/13/spring-3-1-m2-spring-mvc-enhancements/

Spring 3.1 is not released GA yet. Of course, it is available as a milestone release and also as a nightly snapshot. Either way, it is something you should take into consideration and hence worth mentioning.

Upvotes: 4

jtoberon
jtoberon

Reputation: 9016

Please post code samples so that we can better understand what problem you're trying to solve.

Given what you described so far, I don't think this is what a HandlerInterceptor is for. It supposed to be used for cross cutting concerns, yet it's hard to tell from your problem description what's cross cutting. If you want to tie the logic to a controller, then why not modify the controller directly? It sounds like the modification is tightly coupled to the controller anyway, but without more details it's hard to say. That said, here's a related question and answers: HandlerMethod given a HttpRequest?.

Using AOP will get you part of the way there -- at least you'll know more about which controller method is being called. More info: Spring AOP pointcut that matches annotation on interface

Upvotes: 1

Affe
Affe

Reputation: 47954

You cannot tell which method on the handler it's going to actually invoke from inside an interceptor, since the HandlerMapping does not know. That logic is all buried down inside the AnnotationMethodHandlerAdapter, which doesn't really have extension points. You'll need to implement a way to figure out which method it's going to call based on your controller structure if you need that information in the interceptor.

Upvotes: 2

Biju Kunjummen
Biju Kunjummen

Reputation: 49915

AOP will be a good fit for you. You should be able to write an advice which performs your task, with a joinpoint definition capturing the context of the called controller - Any custom annotations that you have, along with the passed parameters.

Upvotes: 4

stimpy
stimpy

Reputation: 492

Have you looked at reflection ?

http://java.sun.com/developer/technicalArticles/ALT/Reflection/

for example

    Class classVar = Class.forName("java.lang.String");

  // getDeclaredFields() returns all the constructors
  Constructor cnstArray[] = classVar.getConstructors();

  // getFields() returns the declared fields 
  Field fldArray[] = classVar.getDeclaredFields();

  // getMethods() returns the declared methods of the class.
  Method mtdArray[] = classVar.getMethods();

Upvotes: 0

Related Questions