malejpavouk
malejpavouk

Reputation: 4445

Spring MVC: how to get a handler method for a request

I am trying to implement some logic depending on annotation present on method with Spring @RequestMapping annotation.

So I have a HttpServletRequest instance in my method and I want to ask spring "give me a method, which will be invoked to handle this request", so I can use reflection API to ask if my annotation is present or not, so I can alter the processing.

Is there any easy way to get this information from Spring MVC?

Upvotes: 4

Views: 15096

Answers (2)

wi2ard
wi2ard

Reputation: 1545

Helped by @ali-dehgani's answer, I have a more flexible implementation that doesn't need to register an interceptor. You do need to pass the request object that is bound to be mapped to that method.

private boolean isHandlerMethodAnnotated(HttpServletRequest request ) {
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
        Map<String, HandlerMapping> handlerMappingMap = BeanFactoryUtils.beansOfTypeIncludingAncestors(webApplicationContext, HandlerMapping.class, true, false);
        try {
            HandlerMapping handlerMapping = handlerMappingMap.get(RequestMappingHandlerMapping.class.getName());
            HandlerExecutionChain handlerExecutionChain = handlerMapping.getHandler(request);
            Object handler = handlerExecutionChain.getHandler();
            if(handler instanceof HandlerMethod){
                Annotation methodAnnotation = ((HandlerMethod) handler).getMethodAnnotation(MyAnnotation.class);
                return methodAnnotation!=null;
            }
        } catch (Exception e) {
            logger.warn(e);
        }
        return false;
    }

Upvotes: 6

Ali Dehghani
Ali Dehghani

Reputation: 48133

I suppose you have a handler method like:

@SomeAnnotation
@RequestMapping(...)
public Something doHandle(...) { ... }

And you want to add some pre-processing logic for all handler methods that are annotated with @SomeAnnotation. Instead of your proposed approach, you can implement the HandlerInterceptor and put your pre-processing logic into the preHandle method:

public class SomeLogicInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, 
                             HttpServletResponse response, 
                             Object handler) throws Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            SomeAnnotation someAnnotation = handlerMethod.getMethodAnnotation(SomeAnnotation.class);
            if (someAnnotation != null) {
                // Put your logic here
            }
        }

        return true; // return false if you want to abort the execution chain
    }
}

Also don't forget to register your interceptor in your web configuration:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SomeLogicInterceptor());
    }
}

Upvotes: 17

Related Questions