一、之前几篇博文阐述了SpringMVC框架开发环境搭建、映射请求的URL以及请求参数的处理过程,下面我们再次回头看下SpringMVC中一个请求周期的流程图
从图例中可以看出一个B/S请求周期是从客户端浏览器开始发起请求,直到服务器端处理完毕当前请求后产生了具体响应的过程,即为一个请求周期,从用户的角度讲,一个请求周期就是单击页面上的某个按钮或链接后,看到结果页面的过程,即为一个请求周期。
因为前几篇博文介绍了在SpringMVC框架中,一个请求的开始、服务器接收请求以及获取请求中参数的过程,那么接下来这篇博文将向大家详细阐述服务器端处理完一个请求后,下一步是怎样向客户端返回结果画面(怎样产生响应的过程)。这里包含了几个方面的知识点,由于时间关系,可能一次不能把这个过程将完毕,相信我会在最短时间内将这一部分内容补齐。就像前面几篇关于SpringMVC的博文一样,大家最终看到都是详细的文章
http://blog.csdn.net/dl0246/article/details/78251319 SpringMVC入门(一)-SpringMVC环境搭建及入门案例(详细)
http://blog.csdn.net/dl0246/article/details/78259612 SpringMVC入门及(二)-SpringMVC请求周期及响应处理(详细)
http://blog.csdn.net/dl0246/article/details/78274343 SpringMVC入门(三)-请求的映射(详细)
http://blog.csdn.net/dl0246/article/details/78286685 SpringMVC入门(四)-SpringMVC在控制器中获取请求中的参数(详细)
http://blog.csdn.net/dl0246/article/details/77996811 SSM框架CRUD操作&批量删除&批量追加数据(Oracle&MySQL数据库)
二、SpringMVC框架响应处理过程
SpringMVC框架究竟是怎样将请求的结果页面给到请求者的呢,我在《SpringMVC系列教程(一)》中有初步的一个阐述,就是通过SpringMVC中的视图映射器InternalResourceViewResolver(org.springframework.web.servlet.view.InternalResourceViewResolver)映射结果页面的。这个对象所要完成的功能即是映射结果页面给请求者,当然这个过程也需要SpringMVC控制器的配合完成页面映射,怎么配合下文将详细阐述,这里先给大家扩展一点小知识。我们知道,视图解析器需要在SpringMVC的配置文件设置的,关于SpringMVC配置文件的简要说明大家可以看下《SpringMVC系列教程(一)》,这里想跟大家扩展说明的是,SpringMVC配置文件的URL可以由开发人员自定义也可以使用SpringMVC的缺省(默认)配置文件。
①、开发人员自定义SpringMVC的配置文件
在web.xml中配置前端控制器时指定SpringMVC配置文件的URL
②、使用SpringMVC的缺省(默认配置文件)
SpringMVC的默认配置文件是和web.xml文件形同目录下,文件名为springDispatcherServlet-servlet.xml,如下图所示
1、视图解析器的最常见映射过程(业务处理方法返回String类型的数据)
细心的网友可能注意到在本系列教程的前几篇博文中,接收请求的Action处理方法的一些细节,即业务请求处理方法的返回值都是String类型的,如下图
可以看到所有方法的返回值都是String类型的,而视图解析器的配置代码如下图:
所以关于SpringMVC响应给请求者的页面的最基本URL为:前缀+String+后缀,比如业务处理方法的返回值是success,如上图视图解析器的配置,响应的URL是类路径下的(WEB-INF)下的/jsp/success.jsp,下面看具体的案例
前端代码:
后端控制器代码:
根据以上案例代码,当用户单击testHello超链接后,系统会将WEB-INF/jsp/success.jsp响应给请求者。
2、ModelAndView
ModelAndView是SpringMVC提供的响应方式之一,是根据实际应用而考量的,单从对象名即可看出,这个对象中既有视图(View)也有模型对象(Model)而且是相互独立的两个组件,View指定了响应的web组件的文件名,而Model指定数据模型对象,SpringMVC将数据模型对象存于request作用域中,所以在web前端jsp中可以通过EL表达式${modelName}获取对象。为给开发人员提供诸多便利,在Spring4.0中ModelAndView对象提供了7个构造器,开发人员可以根据现场情况选择使用,如下图
其中响应的文件名以String或者View接口方式体现,而数据模型对象可以是独立的单一对象也可以封装多个存于Map中,这个Map是java.util包下的Map集合,而SpringMVC底层是将这些对象存于自己封装的对象ModelMap中,ModelMap是LinkedHashMap的子类。下面借助源码理解
①、ModelAndView的源码
②、ModelMap的源码
③、案例代码
④、当然ModelAndView除了以上案例中指定了响应的文件名称,还可以指定一个或者多个模型对象,并且将这些对象存于Request作用域内,在前端页面中就可以通过EL表达式获取这些模型对象的参数值
⑤、View接口
View是在SpringMVC的jar包中提供的一个接口(org.springframework.web.servlet.View),如图:
其中高亮标准的类(RedirectView)是View接口的一个实现类,其源码为
根据以上源码我们可以通过View接口去创建ModelAndView对象,下面给出具体的案例代码如下:
<div>
<a href="springmvc/testView">使用View创建ModelAndView对象</a>
</div>
控制器处理方法代码如下:
/**
* @Author :老张
* @Date :2017年11月1日 上午10:05:59
* @TODO :通过View对象创建ModelAndView
* @return :
*/
@RequestMapping("/testView")
public ModelAndView testView(){
/*
* View是一个接口,RedirectView是其中一个实现类.
* 注意:默认情况下,ModelAndView是在request域中,而通过RedirectView方式响应的话,将以重定向方式响应
*/
View view=new RedirectView("../ForwardAndRedirect.jsp");
ModelAndView modelAndView=new ModelAndView(view);
modelAndView.addObject("user",new User("刘备","admin","liubei@163.com"));
return modelAndView;
}
注意:如果通过RedirectView对象去构建ModelAndView的话,将以重定向方式产生响应,以上案例中的user默认是在request域中,而重定向方式响应的话,结果页面ForwardAndRedirect.jsp将访问不到这个user对象
3、转发和重定向响应方式,相信大家对JavaEE中转发和重定向响应方式的概念以及区别,这里直接给大家上案例,看看在SpringMVC中怎样式实现
①、前端代码
②、后端代码
注意,以上代码可能会导致404错误,因为请求中含有二级目录(springmvc/testForwardAndRedirect),所以响应过程中也会带有二级目录,所以推荐使用绝对路径响应。
③、修改绝对路径的代码
④、redirect方式响应
⑤、有时,开发人员希望将响应的工作交给另外一个控制器方法完成,也就是在一个控制器中调用另一个控制器方法,下面通过案例帮助大家理解
前端代码
<div>
<a href="springmvc/testToOtherAction">从一个控制器跳转到另一个控制器方法</a>
</div>
后端控制器代码
由于时间关系,在SpringMVC中产生响应的方式阐述完了,主要有String、ModelAndView、转发与重定向方式三种响应方式。
2017-11-06日更新
三、SpringMVC作用域及参数处理
1、SpringMVC的作用域和参数一并介绍,因为常规来说,作用域存在的意义就是为了参数的共享,和参数传递一样,都是为在各个web组件间共享数据的目的,比如在Action控制器中从数据库中获取了一个User模型数据对象,而期望这个User对象能够在某一个jsp中使用或者在另一个控制器中访问这个User,此时将涉及到本章介绍的知识。
备注:在这里更大家强调一下,本章讲授内容适用于控制器与web前端(jsp)以及与其他控制器之间的参数处理过程,从jsp发起的请求参数的处理过程在上篇博文详细阐述过了,通过@RequestMapping以及@RequetParam等注解完成。
①、URL地址栏传参,参数传递或者参数共享的最基本最常规方式是通过URL传参,在请求的URL中通过?号引导的参数,当然URL传参中,只能传递字符性质的数据。
如下案例在控制器处理方法中直接通过转发或者重定向方式向目标web组件传递URL参数(注意在SpringMVC中这里都可以传递URL参数,只不过在重定向方式中不能传递汉字参数)
前端页面代码及效果
<body>
ForwardAndRedirect.jsp
<div>
Urlget参数:${param.userid}
</div>
</body>
页面显示效果,见高亮显示部分
重定向结果页面:
转发结果页面:
②、上一章内容介绍的关于响应的对象ModelAndView,其实也能完成参数共享,可以在ModelAndView中存储一个后者多个参数,类型不限。只不过大家要需要记住的是,ModelAndView对象封装的数据默认是Request作用域。
web前端代码
<a href="springmvc/testParam-ModelAndView">通过ModelAndView对象传参</a>
③、自动将模型对象及Map对象存于Request域中,这个在上一章中也涉及到过,就是在控制器的业务处理方法参数中直接定义对象及Map参数,这些参数数据默认都存于Request作用域中
前端代码
<a href="springmvc/testParam-Auto">自动将模型对象及Map对象存于Request域中</a>
④、通过@SessionAttributes()可以将request域中的参数属性存于session域中,这里再次强调,因为SpringMVC自动将参数存于Request域中,所以SpringMVC提供@SessionAttributes()注解完成从Request域到session域的实现过程
注解@SessionAttributes()有两个常用属性,value和types
value:指定从request域获取到的所有对象都存放在session范围内
types:指定从request域获取的所有和types指定的类型一并放在session域内
注意:
A:@SessionAttribuytes的value属性值是作为key去rqeuest域中寻找相关数据有点类似于request.getAttribute(“username”),若在request域中找到了这个对象,SpringMVC会将这个对象存于Session域中
B:@SessionAttributes注解只能用在类上,不能写在方法上面
前端代码
<a href="scope/testReqeustToSession">测试Request域参数到Session域参数(@SessionAttributes)</a>
前端显示效果
补充说明,@ModelAttribute注解,这个注解写在控制器的一个普通方法上面时,这个方法会在任何本控制器方法执行前都会自动执行
/**
* @Author :老张
* @Date :2017年11月3日 下午23:50:54
* @TODO :@ModelAttribute注解的方法在控制器方法运行前都要执行
*/
@ModelAttribute
public void iGo(Map<String,Object> map){
System.out.println("SpringMVCAction.iGo() is running........");
map.put("user",new User("刘备111","admin","liubei@163.com"));
}
⑤、通过Servlet原生API操作作用域,其他操作过程同上
/**
* @Author :老张
* @Date :2017年11月3日 下午23:56:36
* @TODO :通过ServletAPI设置参数,这些对象由SpringMVC底层负责创建,开发人员定义到方法参数中后直接使用即可
* @return :
*/
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,HttpServletResponse response){
System.out.println("BeanAction.testServletAPI() is running......."+request+"\t\n"+response);
request.setAttribute("name", "刘备");
return SCOPE;
}