SpringMVC ModelAndView的用法使用详解
(一)使用ModelAndView类用来存储处理完后的结果数据,以及显示该数据的视图。从名字上看ModelAndView中的Model代表模型,View代表视图,这个名字就很好地解释了该类的作用。业务处理器调用模型层处理完用户请求后,把结果数据存储在该类的model属性中,把要返回的视图信息存储在该类的view属性中,然后让该ModelAndView返回该SpringMVC框架。框架通过调用配置文件中定义的视图解析器,对该对象进行解析,最后把结果数据显示在指定的页面上。
具体作用:
1、返回指定页面
ModelAndView构造方法可以指定返回的页面名称,
也可以通过setViewName()方法跳转到指定的页面,
2、返回所需数值
使用addObject()设置需要返回的值,addObject()有几个不同参数的方法,可以默认和指定返回对象的名字。
1、【其源码】:熟悉一个类的用法,最好从其源码入手。
publicclassModelAndView{ /**ViewinstanceorviewnameString*/ privateObjectview//该属性用来存储返回的视图信息 /**ModelMap*/ privateModelMapmodel;//该属性用来存储处理后的结果数据 /** *Indicateswhetherornotthisinstancehasbeenclearedwithacallto{@link#clear()}. */ privatebooleancleared=false; /** *Defaultconstructorforbean-styleusage:populatingbean *propertiesinsteadofpassinginconstructorarguments. *@see#setView(View) *@see#setViewName(String) */ publicModelAndView(){ } /** *Convenientconstructorwhenthereisnomodeldatatoexpose. *Canalsobeusedinconjunctionwith addObject
. *@paramviewNamenameoftheViewtorender,toberesolved *bytheDispatcherServlet'sViewResolver *@see#addObject */ publicModelAndView(StringviewName){ this.view=viewName; } /** *Convenientconstructorwhenthereisnomodeldatatoexpose. *CanalsobeusedinconjunctionwithaddObject
. *@paramviewViewobjecttorender *@see#addObject */ publicModelAndView(Viewview){ this.view=view; } /** *CreatesnewModelAndViewgivenaviewnameandamodel. *@paramviewNamenameoftheViewtorender,toberesolved *bytheDispatcherServlet'sViewResolver *@parammodelMapofmodelnames(Strings)tomodelobjects *(Objects).Modelentriesmaynotbenull
,butthe *modelMapmaybenull
ifthereisnomodeldata. */ publicModelAndView(StringviewName,Mapmodel){ this.view=viewName; if(model!=null){ getModelMap().addAllAttributes(model); } } /** *CreatesnewModelAndViewgivenaViewobjectandamodel. * Note:thesuppliedmodeldataiscopiedintotheinternal *storageofthisclass.Youshouldnotconsidertomodifythesupplied *Mapaftersupplyingittothisclass *@paramviewViewobjecttorender *@parammodelMapofmodelnames(Strings)tomodelobjects *(Objects).Modelentriesmaynotbenull
,butthe *modelMapmaybenull
ifthereisnomodeldata. */ publicModelAndView(Viewview,Mapmodel){ this.view=view; if(model!=null){ getModelMap().addAllAttributes(model); } } /** *Convenientconstructortotakeasinglemodelobject. *@paramviewNamenameoftheViewtorender,toberesolved *bytheDispatcherServlet'sViewResolver *@parammodelNamenameofthesingleentryinthemodel *@parammodelObjectthesinglemodelobject */ publicModelAndView(StringviewName,StringmodelName,ObjectmodelObject){ this.view=viewName; addObject(modelName,modelObject); } /** *Convenientconstructortotakeasinglemodelobject. *@paramviewViewobjecttorender *@parammodelNamenameofthesingleentryinthemodel *@parammodelObjectthesinglemodelobject */ publicModelAndView(Viewview,StringmodelName,ObjectmodelObject){ this.view=view; addObject(modelName,modelObject); } /** *SetaviewnameforthisModelAndView,toberesolvedbythe *DispatcherServletviaaViewResolver.Willoverrideany *pre-existingviewnameorView. */ publicvoidsetViewName(StringviewName){ this.view=viewName; } /** *ReturntheviewnametoberesolvedbytheDispatcherServlet *viaaViewResolver,or null
ifweareusingaViewobject. */ publicStringgetViewName(){ return(this.viewinstanceofString?(String)this.view:null); } /** *SetaViewobjectforthisModelAndView.Willoverrideany *pre-existingviewnameorView. */ publicvoidsetView(Viewview){ this.view=view; } /** *ReturntheViewobject,ornull
ifweareusingaviewname *toberesolvedbytheDispatcherServletviaaViewResolver. */ publicViewgetView(){ return(this.viewinstanceofView?(View)this.view:null); } /** *IndicatewhetherornotthisModelAndView
hasaview,either *asaviewnameorasadirect{@linkView}instance. */ publicbooleanhasView(){ return(this.view!=null); } /** *Returnwhetherweuseaviewreference,i.e.true
*iftheviewhasbeenspecifiedviaanametoberesolvedbythe *DispatcherServletviaaViewResolver. */ publicbooleanisReference(){ return(this.viewinstanceofString); } /** *Returnthemodelmap.Mayreturnnull
. *CalledbyDispatcherServletforevaluationofthemodel. */ protectedMapgetModelInternal(){ returnthis.model; } /** *Returntheunderlying ModelMap
instance(nevernull
). */ publicModelMapgetModelMap(){ if(this.model==null){ this.model=newModelMap(); } returnthis.model; } /** *Returnthemodelmap.Neverreturnsnull
. *Tobecalledbyapplicationcodeformodifyingthemodel. */ publicMapgetModel(){ returngetModelMap(); } /** *Addanattributetothemodel. *@paramattributeNamenameoftheobjecttoaddtothemodel *@paramattributeValueobjecttoaddtothemodel(never null
) *@seeModelMap#addAttribute(String,Object) *@see#getModelMap() */ publicModelAndViewaddObject(StringattributeName,ObjectattributeValue){ getModelMap().addAttribute(attributeName,attributeValue); returnthis; } /** *Addanattributetothemodelusingparameternamegeneration. *@paramattributeValuetheobjecttoaddtothemodel(nevernull
) *@seeModelMap#addAttribute(Object) *@see#getModelMap() */ publicModelAndViewaddObject(ObjectattributeValue){ getModelMap().addAttribute(attributeValue); returnthis; } /** *AddallattributescontainedintheprovidedMaptothemodel. *@parammodelMapaMapofattributeName->attributeValuepairs *@seeModelMap#addAllAttributes(Map) *@see#getModelMap() */ publicModelAndViewaddAllObjects(MapmodelMap){ getModelMap().addAllAttributes(modelMap); returnthis; } /** *ClearthestateofthisModelAndViewobject. *Theobjectwillbeemptyafterwards. * CanbeusedtosuppressrenderingofagivenModelAndViewobject *inthe
postHandle
methodofaHandlerInterceptor. *@see#isEmpty() *@seeHandlerInterceptor#postHandle */ publicvoidclear(){ this.view=null; this.model=null; this.cleared=true; } /** *ReturnwhetherthisModelAndViewobjectisempty, *i.e.whetheritdoesnotholdanyviewanddoesnotcontainamodel. */ publicbooleanisEmpty(){ return(this.view==null&&CollectionUtils.isEmpty(this.model)); } /** *ReturnwhetherthisModelAndViewobjectisemptyasaresultofacallto{@link#clear} *i.e.whetheritdoesnotholdanyviewanddoesnotcontainamodel. *Returns
false
ifanyadditionalstatewasaddedtotheinstance *afterthecallto{@link#clear}. *@see#clear() */ publicbooleanwasCleared(){ return(this.cleared&&isEmpty()); } /** *Returndiagnosticinformationaboutthismodelandview. */ @Override publicStringtoString(){ StringBuildersb=newStringBuilder("ModelAndView:"); if(isReference()){ sb.append("referencetoviewwithname'").append(this.view).append("'"); } else{ sb.append("materializedViewis[").append(this.view).append(']'); } sb.append(";modelis").append(this.model); returnsb.toString(); }
在源码中有7个构造函数,如何用?是一个重点。
构造ModelAndView对象当控制器处理完请求时,通常会将包含视图名称或视图对象以及一些模型属性的ModelAndView对象返回到DispatcherServlet。
因此,经常需要在控制器中构造ModelAndView对象。
ModelAndView类提供了几个重载的构造器和一些方便的方法,让你可以根据自己的喜好来构造ModelAndView对象。这些构造器和方法以类似的方式支持视图名称和视图对象。
通过ModelAndView构造方法可以指定返回的页面名称,也可以通过setViewName()方法跳转到指定的页面,使用addObject()设置需要返回的值,addObject()有几个不同参数的方法,可以默认和指定返回对象的名字。
(1)当你只有一个模型属性要返回时,可以在构造器中指定该属性来构造ModelAndView对象:
packagecom.apress.springrecipes.court.web; ... importorg.springframework.web.servlet.ModelAndView; importorg.springframework.web.servlet.mvc.AbstractController; publicclassWelcomeControllerextendsAbstractController{ publicModelAndViewhandleRequestInternal(HttpServletRequestrequest, HttpServletResponseresponse)throwsException{ Datetoday=newDate(); returnnewModelAndView("welcome","today",today); } }
(2)如果有不止一个属性要返回,可以先将它们传递到一个Map中再来构造ModelAndView对象。
packagecom.apress.springrecipes.court.web; ... importorg.springframework.web.servlet.ModelAndView; importorg.springframework.web.servlet.mvc.AbstractController; publicclassReservationQueryControllerextendsAbstractController{ ... publicModelAndViewhandleRequestInternal(HttpServletRequestrequest, HttpServletResponseresponse)throwsException{ ... Mapmodel=newHashMap (); if(courtName!=null){ model.put("courtName",courtName); model.put("reservations",reservationService.query(courtName)); } returnnewModelAndView("reservationQuery",model); } }
Spring也提供了ModelMap,这是java.util.Map实现,可以根据模型属性的具体类型自动生成模型属性的名称。
packagecom.apress.springrecipes.court.web; ... importorg.springframework.ui.ModelMap; importorg.springframework.web.servlet.ModelAndView; importorg.springframework.web.servlet.mvc.AbstractController; publicclassReservationQueryControllerextendsAbstractController{ ... publicModelAndViewhandleRequestInternal(HttpServletRequestrequest, HttpServletResponseresponse)throwsException{ ... ModelMapmodel=newModelMap(); if(courtName!=null){ model.addAttribute("courtName",courtName); model.addAttribute("reservations",reservationService.query(courtName)); } returnnewModelAndView("reservationQuery",model); } }
这里,我又想多说一句:ModelMap对象主要用于传递控制方法处理数据到结果页面,
也就是说我们把结果页面上需要的数据放到ModelMap对象中即可,他的作用类似于request对象的setAttribute方法的作用,用来在一个请求过程中传递处理的数据。
通过以下方法向页面传递参数:
addAttribute(Stringkey,Objectvalue);//modelMap的方法
在页面上可以通过el变量方式${key}或者bboss的一系列数据展示标签获取并展示modelmap中的数据。
modelmap本身不能设置页面跳转的url地址别名或者物理跳转地址,那么我们可以通过控制器方法的返回值来设置跳转url地址别名或者物理跳转地址。比如:
publicStringxxxxmethod(Stringsomeparam,ModelMapmodel) { //省略方法处理逻辑若干 //将数据放置到ModelMap对象model中,第二个参数可以是任何java类型 model.addAttribute("key",someparam); ...... //返回跳转地址 return"path:handleok"; }
在这些构造函数中最简单的ModelAndView是持有View的名称返回,之后View名称被viewresolver,也就是实作org.springframework.web.servlet.View接口的实例解析,
例如:InternalResourceView或JstlView等等:ModelAndView(StringviewName);
如果您要返回Model对象,则可以使用Map来收集这些Model对象,然后设定给ModelAndView,使用下面这个版本:
ModelAndView:ModelAndView(StringviewName,Mapmodel),Map对象中设定好key与value值,之后可以在视图中取出
如果您只是要返回一个Model对象,则可以使用下面这个ModelAndView版本:
ModelAndView(StringviewName,StringmodelName,ObjectmodelObject),其中modelName,您可以在视图中取出Model并显示
ModelAndView类别提供实作View接口的对象来作View的参数:
ModelAndView(Viewview) ModelAndView(Viewview,Mapmodel) ModelAndView(Viewview,StringmodelName,ObjectmodelObject)
2【方法使用】:给ModelAndView实例设置view的方法有两个:setViewName(StringviewName)和setView(Viewview)。
前者是使用viewName,后者是使用预先构造好的View对象。其中前者比较常用。事实上View是一个接口,而不是一个可以构造的具体类,我们只能通过其他途径来获取View的实例。对于viewName,它既可以是jsp的名字,也可以是tiles定义的名字,取决于使用的ViewNameResolver如何理解这个viewname。如何获取View的实例以后再研究。
而对应如何给ModelAndView实例设置model则比较复杂。有三个方法可以使用:
addObject(ObjectmodelObject); addObject(StringmodelName,ObjectmodelObject); addAllObjects(MapmodelMap);
3【作用简介】:
ModelAndView对象有两个作用:
作用一:设置转向地址,如下所示(这也是ModelAndView和ModelMap的主要区别)
ModelAndViewview=newModelAndView("path:ok");
作用二:用于传递控制方法处理结果数据到结果页面,也就是说我们把需要在结果页面上需要的数据放到ModelAndView对象中即可,
他的作用类似于request对象的setAttribute方法的作用,用来在一个请求过程中传递处理的数据。通过以下方法向页面传递参数:
addObject(Stringkey,Objectvalue);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。