资源描述
核心架构的具体流程环节如下:
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、解决器(页面控制器)的配置,从而进行功能解决
load-on-startup:表达启动容器时初始化该Servlet;
url-pattern:表达哪些请求交给Spring Web MVC解决, “/” 是用来定义默认servlet映射的。也可以如“*.html”表达拦截所有以html为扩展名的请求。
自此请求已交给Spring Web MVC框架解决,因此我们需要配置Spring的配置文献,默认DispatcherServlet会加载WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml配置文献。本示例为WEB-INF/ chapter2-servlet.xml。
BeanNameUrlHandlerMapping:表达将请求的URL和Bean名字映射,如URL为 “上下文/hello”,则Spring配置文献必须有一个名字为“/hello”的Bean,上下文默认忽略。
SimpleControllerHandlerAdapter:表达所有实现了org.springframework.web.servlet.mvc.Controller接口的Bean可以作为Spring Web MVC中的解决器。假如需要其他类型的解决器可以通过实现HadlerAdapter来解决。
InternalResourceViewResolver:用于支持Servlet、JSP视图解析;
viewClass:JstlView表达JSP模板页面需要使用JSTL标签库,classpath中必须包含jstl的相关jar包;
prefix和suffix:查找视图页面的前缀和后缀(前缀[逻辑视图名]后缀),比如传进来的逻辑视图名为hello,则该该jsp视图页面应当存放在“WEB-INF/jsp/hello.jsp”;
org.springframework.web.servlet.mvc.Controller:页面控制器/解决器必须实现Controller接口,注意别选错了;后边我们会学习其他的解决器实现方式;
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) :功能解决方法,实现相应的功能解决,比如收集参数、验证参数、绑定参数到命令对象、将命令对象传入业务对象进行业务解决、最后返回ModelAndView对象;
ModelAndView:包含了视图要实现的模型数据和逻辑视图名;“mv.addObject("message", "Hello World!");
”表达添加模型数据,此处可以是任意POJO对象;“mv.setViewName("hello");”表达设立逻辑视图名为“hello”,视图解析器会将其解析为具体的视图,如前边的视图解析器InternalResourceVi。wResolver会将其解析为“WEB-INF/jsp/hello.jsp”。
1. <init-param>
2. <param-name>contextConfigLocation</param-name>
3. <param-value>classpath*:/springMVC.xml</param-value>
4. </init-param>
指明了配置文献的文献名,不使用默认配置文献名,而使用springMVC.xml配置文献。
其中<param-value>**.xml</param-value> 这里可以使用多种写法
1、不写,使用默认值:/WEB-INF/<servlet-name>-servlet.xml
2、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
3、<param-value>classpath*:springMVC-mvc.xml</param-value>
4、多个值用逗号分隔
Servlet拦截匹配规则可以自已定义,拦截哪种URL合适?
当映射为@RequestMapping("/user/add")时,为例:
1、拦截*.do、*.htm, 例如:/user/add.do
这是最传统的方式,最简朴也最实用。不会导致静态文献(jpg,js,css)被拦截。
2、拦截/,例如:/user/add
可以实现现在很流行的REST风格。很多互联网类型的应用很喜欢这种风格的URL。
弊端:会导致静态文献(jpg,js,css)被拦截后不能正常显示。想实现REST风格,事情就是麻烦一些。后面有解决办法还算简朴。
3、拦截/*,这是一个错误的方式,请求可以走到Action中,但转到jsp时再次被拦截,不能访问到jsp。
展开阅读全文