【问题标题】:Could Spring MVC call @ModelAttribute after @RequestMapping?Spring MVC 可以在 @RequestMapping 之后调用 @ModelAttribute 吗?
【发布时间】:2013-07-26 04:21:10
【问题描述】:

我有一个这样的控制器:

@Controller
public class HomeController {

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(@RequestParam("user") User user, ModelMap model){
        SaveUserToDatabase(user);
        return "index";
    }

    @ModelAttribute("user")
    String getUser() {
        return LoadCurrentUserFromDataBase();
    }
}

简而言之,我的观点会在HomeController 中的几乎每个 操作中呈现user, 但我不想编码:

model.addAttribute("user", LoadCurrentUserFromDataBase())

在每一个动作中,我都在寻找一种像 @ModelAttribute 这样的方式来将 user 暴露给我的所有观点。

但是,根据文档,控制器中的 @ModelAttribute 方法在同一控制器内 @RequestMapping 方法之前被调用。

至于我的代码,getUserupdate 之前被调用,但我想获取更新的用户。

有没有办法暴露user 属性after 动作而不在每个动作中显式调用model.addAttribute

【问题讨论】:

    标签: java spring spring-mvc modelattribute


    【解决方案1】:

    每次您执行POST 时,都会进行重定向。这样你的POST方法就只负责更新数据,更新后的数据会被目标控制器加载。

    因此在这种情况下,update() 方法将重定向到另一个控制器,该控制器将在其 GET 方法之前调用 getUser() 方法。

    【讨论】:

      【解决方案2】:

      Post/redirect/GET 解决方案如果适合您,则有效。

      但是,我遇到了类似的情况,在请求处理之后(主要是跟踪信息),我的所有控制器都需要编写模型属性。我所做的是注册一个自定义接口(例如AdditionalModelDataSupplier),我将其应用于所有需要提供额外数据的控制器。接口会有这样的方法:

      void provideAdditionalData(Model model, HttpServletRequest request);
      

      现在,我写了一个拦截器,在postHandle 方法中检查Controller bean 是否有这个接口并调用这个方法:

      @Override
      public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler,
              final ModelAndView modelAndView) throws Exception {
      
          AdditionalModelDataSupplier modelDataSupplier = findAdditionalModelDataSupplier(handler);
          if (modelDataSupplier != null) {
              final ModelMap modelMap = modelAndView.getModelMap();
              final Model targetModel;
              if (modelMap instanceof Model) {
                  targetModel = (Model) modelMap;
              } else {
      
                  // the modelmap doesn't implement model, so we need to provide a wrapper view
                  targetModel = new ForwardingModel(modelMap);
              }
      
              modelDataSupplier.provideAdditionalData(targetModel, request);
          }
      }
      @Nullable
      private static AdditionalModelDataSupplier findAdditionalModelDataSupplier(final Object handler) {
          if (handler instanceof AdditionalModelDataSupplier) {
              return (AdditionalModelDataSupplier) handler;
          }
      
          if (handler instanceof HandlerMethod) {
              HandlerMethod handlerMethod = (HandlerMethod) handler;
              Object bean = handlerMethod.getBean();
              if (bean instanceof AdditionalModelDataSupplier) {
                  return (AdditionalModelDataSupplier) bean;
              }
          }
      
          return null;
      }
      

      (上面提到的ForwardingModel 类创建起来很简单,它只是将所有内容委托给ModelMap

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-20
        • 1970-01-01
        相关资源
        最近更新 更多