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

时间:2013-07-26 03:00:37

标签: java spring spring-mvc modelattribute

我有一个像这样的控制器:

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

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

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

在每项操作中,相反,我正在寻找像@ModelAttribute这样的方式向我的所有观点展示user

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

至于我的代码,getUser之前调用update,但我想获得更新的用户。

有没有办法在操作后公开user属性而不在每个操作中明确调用model.addAttribute

2 个答案:

答案 0 :(得分:5)

每次执行POST时,请进行重定向。这样,您的POST方法只负责更新数据,更新的数据将由目标控制器加载。

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

答案 1 :(得分: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