Spring Controllers: Can I call a method before each @RequestMapping method is called?

我的梦境 提交于 2021-02-17 14:42:23

问题


I have some common components that are always present in every page served by a given Controller class.

At the beginning of each @RequestMapping method I populate the model with these common components.

Is there a way to define a method be called prior to each of the controller methods so that I can get all of this copy/paste into one place?


回答1:


Just annotate a method with @ModelAttribute

The below would add a Foo instance to the model under the name "foo"

@ModelAttribute("foo")
public Foo foo() {
    return new Foo();
}

See the @ModelAttribute documentation




回答2:


Interceptor is the solution. It has methods preHandler and postHandler, which will be called before and after each request respectively. You can hook into each HTTPServletRequest object and also by pass few by digging it.

here is a sample code:

@Component
public class AuthCodeInterceptor extends HandlerInterceptorAdapter {

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

        // set few parameters to handle ajax request from different host
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        response.addHeader("Access-Control-Max-Age", "1000");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
        response.addHeader("Cache-Control", "private");

        String reqUri = request.getRequestURI();
        String serviceName = reqUri.substring(reqUri.lastIndexOf("/") + 1,
                reqUri.length());
                if (serviceName.equals("SOMETHING")) {

                }
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {

        super.postHandle(request, response, handler, modelAndView);
    }
}



回答3:


All methods that have the @ModelAttribute annotation are called before the specific handler and the return values are added to the Model instance. Then you can use this attributes in your views and as handler parameters.

I found this blog very useful.




回答4:


Yes, you can use an interceptor. You can define them by <mvc:interceptors>

Another option is to use s Filter, but you won't be able to inject spring beans into it.




回答5:


Another approach would be to annotate the controller class as request-scoped (@Scope('request')) so that every request will create a new instance of the controller to invoke the matching method on it.

You can then put all your pre-processing work into a post-construct method (i.e. a normal method annotated with @PostConstruct) which will always be called after a new controller instance is initialized (i.e created and all dependencies are resolved) and before the request-matching method is invoked.

I suppose that this would be a bit inefficient if controller's initialization is heavy (e.g. costly computations or many dependencies to resolve); but yet is another approach to this problem.



来源:https://stackoverflow.com/questions/5088179/spring-controllers-can-i-call-a-method-before-each-requestmapping-method-is-ca

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!