我可以在Spring MVC中的ModelAndView中返回两个模型

时间:2011-02-21 17:05:08

标签: java spring spring-mvc

如果我有一个模型

,假设我有以下代码
MyBean bean = new MyBean();
bean.setName("Mike");
bean.setMessage("Meow!");

return new ModelAndView("welcomePage","model",bean);

但如果我有两个或三个模型,如

假设在我的一个观点上  我希望模型包含用户详细信息,购物车详细信息和历史记录详细信息

我如何使用ModelAnd View返回2-3个模型

3 个答案:

答案 0 :(得分:34)

您可以通过多种方式实现这一目标,但也许最简单的方法是使用地图

Map<String, Object> model = new HashMap<String, Object>();
model.put("bean", bean);
model.put("userdetails", userdetails);
//and so on
return new ModelAndView("welcomePage", "model", model);

然后,在您的页面中,您只需在访问时添加额外的级别

User's name is ${ model.userdetails.username }

或者,您也可以将处理程序签名更改为此类

public String handleRequest(Model model){
   //arbitrary handling code
   model.addAttribute("bean", bean);
   model.addAttribute("userdetails", userdetails);
   //etc
   return "welcomePage";
 }

当你这样做时,你实际上不必返回模型,因为Spring在你收到它之前会保留它,然后可以访问它。我个人认为这种方法更好一点,因为它使单元测试更容易。您所要做的就是检查字符串返回值并使用Spring模型(或您自己的实现Model接口的模拟对象)。

修改要发表评论:

This source给出了一些示例,并讨论了一些支持的方法签名。具体来说,请查看第15.3.2.3节,了解可以传递给处理程序方法的参数。

基本上,Spring使用@RequestMapping注释来确定应根据给定请求调用哪些方法。然后,Spring可以在调用方法之前检查方法签名并生成适当的参数。在返回ModelAndView对象的情况下,根据您提供的参数调用构造函数时会创建Model。如果未提供任何模型对象,则会创建空模型。但是,当您指定应将模型作为处理程序方法的参数接收时,Spring会为您创建一个Model对象的实例,并将其传递给您的方法。 Spring保留对该模型的引用,并且当您的方法返回时,将该模型传递给Web视图(例如JSP解析器)。

它实际上与返回ModelAndView对象实际上是相同的,除了它使单元测试更容易和坦率地说,IMO使得更清洁和更优雅的实现。

注意:请记住,Model实际上只是一个特殊的Map对象(因此Spring支持在方法签名中互换使用ModelMap) 。还有一些其他方法,它还支持隐式属性命名。例如,如果您只是简单地传递一个对象而没有给它命名,Model对象将根据对象类型等确定对象的名称。但是,如果您总是提供一个“键”您添加到模型的对象,其行为与Map完全相同。

答案 1 :(得分:6)

是的,您可以通过将任意数量的模型属性放入Map

来返回这些属性
Map<String, Object> model = new HashMap<String, Object>();
model.put("model", bean);
model.put("userdetails", ...);
model.put("shoppingcart", ...);
return new ModelAndView("welcomePage", model);

注意术语 - 模型是一个地图,它由模型属性(单个对象)组成,new ModelAndView("welcomePage","model",bean)是一个方便构造函数,用于创建具有单个属性的模型。

答案 2 :(得分:0)

有很好的例子。只是为了增加组合,我真的成为了基于注释的方法的粉丝。我喜欢它,因为它提供了一种非常干净的实现方式。这是一个例子......

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@Scope("prototype")
@RequestMapping("/testing")
public class TestController {

    @Autowired
    TestFactory factory;

    @RequestMapping(value = "/test1", method = RequestMethod.POST)
    public void test1(String something, String something2, Model model) {
        List<Map<String, String>> results = 
             factory.getSomethingCool(something1, something2);

        model.addAttribute("something1", something1);
        model.addAttribute("something2", something2);
        model.addAttribute("results", results);
    }

    @RequestMapping(value = "/test2", method = RequestMethod.POST)
    public void test1(String something1, String something2, Model model) {
        List<String> results = 
            factory.getSomethingElseCool(something1, something2);

        model.addAttribute("something1", something1);
        model.addAttribute("something2", something2);
        model.addAttribute("results", results);
    }
}