【问题标题】:Setting model attributes for every action within each controller为每个控制器中的每个操作设置模型属性
【发布时间】:2017-11-06 04:14:12
【问题描述】:

我想在我的模型上为 Spring Boot 应用程序的许多控制器中的每个 @RequestMapping 设置三个通用属性。我已经阅读了有关@ModelAttribute 的信息,但它需要放置在每个控制器中。我的应用程序中有 20 多个控制器,每个控制器都有超过 10 个 @RequestMapping

有没有办法在应用程序启动时初始化的地方设置此类模型属性?

【问题讨论】:

  • 引入一个通用的BaseController类并将@ModelAttribute放在类中,让你所有的控制器扩展BaseController
  • 这就是使用@ControllerAdvice 注释的类可以为您做的事情。或者使用HandlerInterceptor 在每个请求中添加公共数据。

标签: java spring spring-mvc model-view-controller spring-boot


【解决方案1】:

如果你想在 Spring Boot 启动时执行一些代码,考虑这个:

Spring boot startup listener

但我猜你确实想要与控制器相关的行为我建议使用全局拦截器

使用全局拦截器,您可以干扰 Spring 中的请求-响应生命周期。

它允许您在 3 个不同的点向请求-响应生命周期添加功能:

  1. 在控制器处理请求之前
  2. 处理程序完成其功能后
  3. 当视图即将呈现给最终用户时。

只需创建一个从 HandlerInterceptorAdapter 扩展的类,并使用您想要的功能覆盖三个方法之一。

例如:

public class MyInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        request.setAttribute("myFirstAttribute", "MyFirstValueHere");
        return super.preHandle(request, response, handler);
    }

}

这是一个如何使用 Spring Boot 的示例:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

  @Autowired 
  MyInterceptor myInterceptor;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(...)
    ...
    registry.addInterceptor(myInterceptor);
  }
}

【讨论】:

  • 在这种情况下,属性是在请求而不是模型上设置的。我说的对吗?
  • 我相信最终它也会被设置在模型上。使用请求参数
  • 那不涉及在模型上设置它们的另一个步骤吗?
  • 不需要进一步的步骤,请求集参数将完成这项工作
  • 我的意思是使用我原来的解决方案 + 尝试像通常使用模型属性一样读取 JSP 上的参数
【解决方案2】:

我通过SpringMVC提供了另一种方法,使用HandlerInterceptor,当你实现它时,它提供了3个方法,每个方法都包含HttpServletRequest,你可以使用request.setAttribute("xx","yy")设置属性,代码如下:

public class RequestInterceptor implements HandlerInterceptor {

    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {

    }

    public void postHandle(HttpServletRequest request, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
      //you can set attributes here like request.setAttribute("xx","yy")
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
            Object arg2) throws Exception {
        //you can set attributes here like request.setAttribute("xx","yy")
        return false;
    }

}

然后,您需要将自定义拦截器添加到您的 spring mvc 应用程序中,如下所示:

<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
   <property name="interceptors">
    <list>
      <!--class of your custom interceptor-->
      <bean class="com.xx.RequestInterceptor"/>
    </list>
   </property>
</bean>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-01
    • 2014-04-09
    • 1970-01-01
    • 2021-01-17
    • 2023-03-21
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    相关资源
    最近更新 更多