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
方法之前被调用。
至于我的代码,getUser
在update
之前被调用,但我想获取更新的用户。
有没有办法暴露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 Boot教程 springboot程序构建一个docker镜像