简体   繁体   English

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

[英]Can i return two models in ModelAndView in Spring MVC

Suppose i have following code if i have one model 如果我有一个型号,假设我有以下代码

MyBean bean = new MyBean();
bean.setName("Mike");
bean.setMessage("Meow!");

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

But if i have two or three models like 但如果我有两个或三个模型

Suppose on my one view i want the model with userdetails , shoppingcart details and history details 假设在我的一个视图中,我希望模型具有用户详细信息,购物车详细信息和历史记录详细信息

how can i use ModelAnd View to return 2-3 models 我如何使用ModelAnd View返回2-3个模型

You can accomplish this a number of ways, but perhaps the easiest way would be to use a map 您可以通过多种方式实现此目标,但也许最简单的方法是使用地图

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);

Then, in your page, you just have to add an extra level when you access it 然后,在您的页面中,您只需在访问它时添加额外的级别

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

alternatively, you could also change your handler signature to be something like this 或者,您也可以将处理程序签名更改为此类型

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

When you do it like this, you don't actually have to return the model because Spring holds on to the reference before you receive it and can then access it afterwards. 当你这样做时,你实际上不必返回模型,因为Spring在你收到它之前会保留它,然后可以访问它。 I personally find this method a little better because it makes unit testing easier. 我个人认为这种方法更好一点,因为它使单元测试更容易。 All you have to do is check the string return value and use a Spring mock model (or your own mock object that implements the Model interface). 您所要做的就是检查字符串返回值并使用Spring模型(或您自己的模拟对象实现Model接口)。

Edit To address the comments: 编辑要解决评论:

This source gives some examples and discusses some of the various supported method signatures. 此源提供了一些示例,并讨论了一些支持的方法签名。 Specifically, check out section 15.3.2.3 for a discussion of the parameters that can be passed to handler methods. 具体来说,请查看第15.3.2.3节,了解可以传递给处理程序方法的参数。

Basically, Spring uses the @RequestMapping annotations to determine which methods should be called based on a given request. 基本上,Spring使用@RequestMapping注释来确定应根据给定请求调用哪些方法。 Spring is then able to examine the method signature and generate the appropriate parameters before calling the method. 然后,Spring可以在调用方法之前检查方法签名并生成适当的参数。 In the case where you return a ModelAndView object, the Model is created when the constructor is called based on the parameters you provide. 在返回ModelAndView对象的情况下,根据您提供的参数调用构造函数时,将创建Model If you don't provide any model objects, then an empty model is created. 如果未提供任何模型对象,则会创建空模型。 However, when you specify that you should receive the model as a parameter to your handler method, Spring creates an instance of a Model object for you and passes it to your method. 但是,当您指定应将模型作为处理程序方法的参数接收时,Spring会为您创建一个Model对象的实例并将其传递给您的方法。 Spring holds on to a reference to that model and, when your method returns, passes that model along to the web view (for example a JSP parser). Spring保留对该模型的引用,并且当您的方法返回时,将该模型传递给Web视图(例如JSP解析器)。

It really is effectively the same as returning a ModelAndView object except it makes unit testing a lot easier and frankly, IMO makes for a cleaner and more elegant implementation. 它实际上与返回一个ModelAndView对象实际上是相同的,除了它使得单元测试变得更加容易和坦率地说,IMO使得实现更清晰,更优雅。

Note: Keep in mind that a Model is really just a special Map object (hence why Spring supports using a Model or Map interchangeably in the method signatures). 注意:请记住, Model实际上只是一个特殊的Map对象(因此Spring支持在方法签名中交替使用ModelMap )。 There are a few additional methods and it also supports implicit attribute naming. 还有一些其他方法,它还支持隐式属性命名。 For instance, if you were to simply pass an object without giving it a name, the Model object will figure out what to name the object based on object type, etc. However, if you always provide a "key" for the object you add to the model, it behaves exactly the same as a Map . 例如,如果您只是简单地传递一个对象而没有给它命名,那么Model对象将根据对象类型等确定对象的名称。但是,如果您总是为添加的对象提供“键”对于模型,它的行为与Map完全相同。

Yes, you can return arbitrary number of model attributes by placing them into Map : 是的,您可以通过将任意数量的模型属性放入Map来返回它们:

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

Note the terminology - model is a map, it consists of model attributes (individual objects), new ModelAndView("welcomePage","model",bean) is a convenience constructor for creating a model with a single attribute. 注意术语 - 模型是一个映射,它由模型属性(单个对象)组成, new ModelAndView("welcomePage","model",bean)是一个方便的构造函数,用于创建具有单个属性的模型。

There are good examples given. 给出了很好的例子。 Just to add to the mix, I'm really becoming a fan of the annotations based methodology of doing this. 只是为了增加组合,我真的成为了基于注释的方法的粉丝。 I like it because it provides a very clean way of implementing. 我喜欢它,因为它提供了一种非常干净的实现方式。 Here is an example... 这是一个例子......

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM