Spring 控制器:我可以在调用每个 @RequestMapping 方法之前调用一个方法吗?

发布于 2024-10-18 22:33:22 字数 144 浏览 3 评论 0原文

我有一些通用组件,它们始终存在于给定控制器类提供的每个页面中。

在每个 @RequestMapping 方法的开头,我使用这些通用组件填充模型。

有没有一种方法可以定义在每个控制器方法之前调用的方法,以便我可以将所有这些复制/粘贴到一个地方?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一曲琵琶半遮面シ 2024-10-25 22:33:22

只需使用 @ModelAttribute 注释一个方法,

下面将以名称“foo”向模型添加一个 Foo 实例,

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

请参阅 @ModelAttribute 文档

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

聚集的泪 2024-10-25 22:33:22

拦截器就是解决方案。它有 preHandler 和 postHandler 方法,分别在每次请求之前和之后调用。您可以挂钩每个 HTTPServletRequest 对象,也可以通过挖掘它来绕过一些对象。

这是示例代码:

@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);
    }
}

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);
    }
}
盗心人 2024-10-25 22:33:22

所有具有 @ModelAttribute 注释的方法都会在特定处理程序之前调用,并将返回值添加到 Model 实例。然后您可以在视图中使用此属性并将其用作处理程序参数。

我发现此博客非常有用。

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.

薆情海 2024-10-25 22:33:22

是的,您可以使用 拦截器。您可以通过 定义它们

另一种选择是使用 Filter,但您无法将 spring beans 注入其中。

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.

土豪 2024-10-25 22:33:22

另一种方法是将控制器类注释为请求范围 (@Scope('request')),以便每个请求都将创建控制器的一个新实例来调用其上的匹配方法。

然后,您可以将所有预处理工作放入构造后方法(即用@PostConstruct注释的普通方法)中,该方法将始终在初始化新控制器实例(即创建并且所有依赖关系已解决)并且在调用请求匹配方法之前。

我认为如果控制器的初始化很繁重(例如昂贵的计算或需要解决许多依赖项),这会有点低效;但这是解决这个问题的另一种方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文