ModelAndView 类别就如其名称所示,是代表了Spring Web MVC程式中呈现画面时所使用Model资料物件与View资料物件,由于Java程式中一次只能返回一个物件,所以ModelAndView的作用封装这两个物件,以方便您一次返回Model与View这两个物件。
最简单的ModelAndView是持有View的名称返回,之后View名称被View resolver,也就是实作org.springframework.web.servlet.View介面的实例解析,例如 InternalResourceView或JstlView等等,最简单的ModelAndView建构方式如下:
如果您要返回呈现画面时所需的Model资料物件,则可以使用Map物件来收集呈现资料时所需的资料,然后在建构ModelAndView作为建构时的引数,您可以使用下面这个版本的ModelAndView建构方法:
Map物件中设定好键(Key)与值(Value),之后可以在要呈现的画面中取出加以显示(例如在JSP网页中),如果您要返回一个Model资料物件并指定Model的名称,则可以使用下面这个ModelAndView版本:
藉由modelName,您可以在要View的实作类别中取出Model资料物件,并根据View所使用的技术来加以显示(可能是JSP网页、Pdf等呈现技术)。
ModelAndView类别也提供实作View介面的物件来作为建构时的引数,以下是三个可用的建构方法版本:
ModelAndView(View view, Map model)
ModelAndView(View view, String modelName, Object modelObject)
一个实作View的实例例是org.springframework.web.servlet.view.RedirectView, ModelAndView预设是使用转发(Forward)方式来完成请求的结果画面,使用RedirectView的话,则会使用重新导向(Redirect)将请求重导至指定的结果画面位置,以呈现请求的结果,例如:
public ModelAndView handleRequest(....) ... {
...
return new ModelAndView(
new RedirectView(this.getViewPage()));
}
...
在这边,viewPage所设定的位址要是从伺服器网页根目录开始指定,而不是Web应用程式的根目录,所以您的getViewPage()传回的位址必须像是/FirstSpringMVC/pages/index.htm这样的位址,其中FirstSpringMVC是您的Web应用程式目录。
使用转发(Forward)方式的话,网址列上并不会出现被转发的目标位址,而且转发方式是在Web应用程式之内进行,可以访问Web应用程式所设定的内部目录,像是WEB-INF目录,因而您可以将一些要控管存取的资源放到WEB-INF下,如此使用者就无法直接请求这些资源,而必须透过 DispatcherServlet与Controller的处理与控管,才可以取得这些资源,转发方式只能在Web应用程式中进行,不能指定至其它的 Web应用程式位址。
使用重新导向(Redirect)的话,Web应用程式会要求客户端浏览器重新发出一个所指定的请求位址,也就是实际上相当于客户端重新连接至一个所指定的位址,因此浏览器的位址列上会出现被重新导向的资讯,重新导向的请求是由浏览器发出,所以不能访问Web应用程式中的隐藏目录,像是WEB-INF,重新导向是重新要求一个网页,所以可以指定至其它的Web应用程式位址。
DispatcherServlet会根据传回的ModelAndView来解析View名称,并处理给予的Model。
View名称的解析是委托给实作org.springframework.web.servlet.ViewResolver介面的实例,ViewResolver介面定义如下:
public interface ViewResolver { public view resolveViewName( String , Locale locale) throws ServletException; }
ViewResolver的一个实例是InternalResourceViewResolver,名称解析完之后,实际的View绘制与Model转换处理是交给实作org.springframework.web.servlet.View的实例,View介面如下:
public interface View { public void render(Map model, HttpServletResquest resquest, HttpServletResponse response) throws ServletException, IOException; }
View的实作之前用过org.springframework.web.servlet.view.InternalResourceView,另外也还有JstlView、TilesView、VelocityView等等的实作,分别进行不同的表现展处理。