Могу ли я вернуть две модели в ModelAndView в Spring MVC

Предположим, что у меня есть следующий код, если у меня есть одна модель

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

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

Но если у меня есть две или три модели, такие как

Предположим, что на моем одном представлении  Я хочу, чтобы модель с пользовательскими деталями, сведениями о деталях покупок и подробностями истории

как я могу использовать ModelAnd View для возврата 2-3 моделей

Ответ 1

Вы можете сделать это несколькими способами, но, возможно, самым простым способом было бы использовать карту

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

Изменить. Чтобы отправить комментарии:

В этом источнике приведены некоторые примеры и обсуждаются некоторые из поддерживаемых сигнатур методов. В частности, ознакомьтесь с разделом 15.3.2.3 для обсуждения параметров, которые могут быть переданы методам обработчика.

В принципе, Spring использует аннотации @RequestMapping, чтобы определить, какие методы следует вызывать на основе данного запроса. Spring затем может проверить подпись метода и сгенерировать соответствующие параметры перед вызовом метода. В случае, когда вы возвращаете объект ModelAndView, Model создается, когда конструктор вызывается на основе параметров, которые вы предоставляете. Если вы не предоставляете никаких объектов модели, создается пустая модель. Однако, когда вы укажете, что вы должны получить модель в качестве параметра для вашего метода обработчика, Spring создает экземпляр объекта Model для вас и передает его вашему методу. Spring относится к ссылке на эту модель и, когда ваш метод возвращает, передает эту модель вместе с веб-представлением (например, парсер JSP).

Это действительно так же, как возврат объекта ModelAndView, за исключением того, что модульное тестирование намного проще и, честно говоря, ИМО делает более чистую и элегантную реализацию.

Примечание. Имейте в виду, что Model на самом деле просто специальный Map объект (поэтому почему Spring поддерживает использование Model или Map взаимозаменяемо в сигнатурах метода). Существует несколько дополнительных методов, а также поддерживает неявное присвоение атрибутов. Например, если вы просто передали объект, не указав его имя, объект Model будет определять, как назвать объект на основе типа объекта и т.д. Однако, если вы всегда предоставляете "ключ" для объекта вы добавляете к модели, она ведет себя точно так же, как Map.

Ответ 2

Да, вы можете вернуть произвольное количество атрибутов модели, поместив их в 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) - конструктор удобства для создания модели с одним атрибутом.

Ответ 3

Есть хорошие примеры. Чтобы добавить в микс, я действительно становлюсь поклонником методологии, основанной на аннотациях. Мне это нравится, потому что он обеспечивает очень чистый способ реализации. Вот пример...

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