《跟我学SpringMVC》第二章笔记
Spring Web MVC处理请求的流程:
具体步骤:
1、 首先用户发送请求————>前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图2-1中的1、2步骤;
2、 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图2-1中的3、4、5步骤;
3、 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图2-1中的步骤6、7;
4、 前端控制器再次收回控制权,将响应返回给用户,图2-1中的步骤8;至此整个结束。
Spring Web MVC架构:
核心架构的具体流程步骤如下:
1、 首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、 DispatcherServlet——>HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、 DispatcherServlet——>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、 HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5、 ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、 View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
此处我们只是讲了核心流程,没有考虑拦截器、本地解析、文件上传解析等,后边再细述。
1、 请求如何给前端控制器?这个应该在web.xml中进行部署描述,在HelloWorld中详细讲解。
2、 前端控制器如何根据请求信息选择页面控制器进行功能处理? 我们需要配置HandlerMapping进行映射
3、 如何支持多种页面控制器呢?配置HandlerAdapter从而支持多种类型的页面控制器
4、 如何页面控制器如何使用业务对象?可以预料到,肯定利用Spring IoC容器的依赖注入功能
5、 页面控制器如何返回模型数据?使用ModelAndView返回
6、 前端控制器如何根据页面控制器返回的逻辑视图名选择具体的视图进行渲染? 使用ViewResolver进行解析
7、 不同的视图技术如何使用相应的模型数据? 因为Model是一个Map数据结构,很容易支持其他视图技术
在此我们可以看出具体的核心开发步骤:
1、 DispatcherServlet在web.xml中的部署描述,从而拦截请求到Spring Web MVC
2、 HandlerMapping的配置,从而将请求映射到处理器
3、 HandlerAdapter的配置,从而支持多种类型的处理器
4、 ViewResolver的配置,从而将逻辑视图名解析为具体视图技术
5、处理器(页面控制器)的配置,从而进行功能处理
HelloWorld实例里面踩到的坑:
一、 Spring框架依赖的jar包:
1 需要添加Apache commons logging日志,此处使用的是commons.logging-1.1.1.jar;
2 需要添加jstl标签库支持,此处使用的是jstl-1.1.2.jar和standard-1.1.2.jar;
我用的intellij编译器,通过maven来配置的开发环境,maven配置依赖jar包是在pom文件中通过<dependency>标签自动导入jar包。
首先这几个需要的jar包里面,spring的jar包公司里面的项目里都有,我直接copy的,但是1、2所需要的jar包没有,于是我自己去网上搜索了一番,终于找到了相应的配置。
二、Mark As
这一步很重要,一开始我连创建个class文件都创建不了,百度得知在创建工程的时候要先Mark好了每一部分的分工,这样有些格式的文件才可以创建。
三、hello.jsp界面${message}不能翻译成hello world
找了半天不知道什么原因,首先${}不是jsp的语法,是EL表达式,而EL表达式。百度得知,jsp版本只有2.0是默认开启支持EL表达式的,因此要主动将它开启,<%@ page isELIgnored="false" %>。或者一种一劳永逸的方法,在web.xml里面把web-app修改,
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
改成这样就完事了。
四、设置filter
在web.xml文件里面配置filter,一开始配置完了,<web-app>标签一直报错显示红色,找了半天不知道为啥,后来百度查资料,看到了这个回答
如果你用的是http://java.sun.com/dtd/web-app_2_3.dtd,那么你web-app中元素是有顺序的:
XML code<!ELEMENT web-app (icon?, display-name?, description?, distributable?,
context-param*, filter*, filter-mapping*, listener*, servlet*,
servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?,
error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*,
login-config?, security-role*, env-entry*, ejb-ref*, ejb-local-ref*)>
原来是顺序问题我靠,果然按照这个顺序改了一下,一下就跑通了。
总结一下,今天踩了这四个坑,写个HelloWorld写了我一天也是醉了。不过得出了这些宝贵的经验,下次再碰到这些问题的时候就能顺利解决了。任重道远。
附上一**解的意义:
@Controller:用于标识是处理器类;
@RequestMapping:
请求到处理器功能方法的映射规则;
@RequestParam:
请求参数到处理器功能处理方法的方法参数上的绑定;
@ModelAttribute:
请求参数到命令对象的绑定;
@SessionAttributes:
用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中;
@InitBinder:
自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;
RESTFUL风格:
@CookieValue:
cookie数据到处理器功能处理方法的方法参数上的绑定;
@RequestHeader:
请求头(header)数据到处理器功能处理方法的方法参数上的绑定;
@RequestBody:
请求的body体的绑定(通过HttpMessageConverter进行类型转换);
@ResponseBody:
处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);
@ResponseStatus:
定义处理器功能处理方法/异常处理器返回的状态码和原因;
@ExceptionHandler:
注解式声明异常处理器;
@PathVariable:
请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI;