Spring MVC 可以在 @RequestMapping 之后调用 @ModelAttribute 吗?

Posted

技术标签:

【中文标题】Spring MVC 可以在 @RequestMapping 之后调用 @ModelAttribute 吗?【英文标题】:Could Spring MVC call @ModelAttribute after @RequestMapping? 【发布时间】: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

【问题讨论】:

【参考方案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

【讨论】:

以上是关于Spring MVC 可以在 @RequestMapping 之后调用 @ModelAttribute 吗?的主要内容,如果未能解决你的问题,请参考以下文章

spring mvc中如何读取数据库

Spring Boot教程 springboot程序构建一个docker镜像

spring mvc 跟 maven spring mvc 有啥区别

spring mvc 客户端到服务器端的list参数传递

使用spring mvc 怎么在后台接收空的整型数据。

Spring MVC文件上传