来自《Spring揭秘》一书~
1 Servlet
Servlet是Java平台上第一个Web开发的技术,但在其doGet/doPost方法内逻辑混乱 --> Magic Servlet
对其中out.println等视图表现的部分进行抽取,形成了jps表现模式,JSP时代来临 --> Magic JSP
经过JSP Model1时代后,在JSP Model2时代,Web容器三分天下,MVC形成:
- Servlet 管理处理流程
- JSP 视图渲染
- JavaBean 封装业务逻辑/与数据层交互
2 Web框架
2.1 分为两类:
- 请求驱动型
- 事件驱动型 基于组件的Web开发框架,将视图组件化,由视图中的组件触发事件,进而驱动整个流程
我们大部分用请求驱动型,为了解决JSP Model2的问题,有如下特点:
2.2 Controller进一步分层:
- Front Controller 一级控制器
- Page Controller 次级控制器
原先: 单一的控制器Servlet通过将流程控制信息外部化,并分离具体的Web请求处理逻辑给次级控制器类进行处理
现在: 瘦身为灵活而可复用的担当Front Controller的Servlet
3 Spring MVC
3.1 在Spring MVC中,两层控制器对应如下:
Front Controller:DispatcherServlet
Page Controller:org.springframework.web.servlet.mvc.Controller (一般是集成AbstractController)
3.2 各种角色:
DispatcherServlet 最先执行
HandlerMapping 连接两层控制器的桥梁,
Controller 返回 ModelAndView
ViewResolver 返回View,比如*.jsp
View 渲染输出,在mcs等工程中,是直接通过reponse.getOutPutSream输出流输出的,不是通过jsp页面
4 MVC的物理结构:web.xml
其实web.xml可以大致分为两大部分:
- 加载WebApplicationContext
- 加载以DispatcherServlet为中心的控制器环境
4.1 WebApplicationContext:ContextLoaderListener
ApplicationContext的加载,是通过ContextLoaderListener类来实现的,默认加载WEB-INF下的applictionContext.xml
怎么自己设置加载的文件呢,毕竟不能把所有配置都放在一个applictionContext.xml里面,况且路径也未必是WEB-INF下:通过contextConfigLocation属性配置
4.2 DispatcherServlet
DispatcherServlet这个一级控制器的加载,要略微复杂些:
1 定义DispatcherServlet
注意,load-on-startup指定启动顺序,数字越小,优先级越高。而且,这个控制器名为rest
2 指定url<->DispatcherServlet之间的关系
这样,一个如http://127.0.0.1:8181/api/23423rw的url过来,就可以被rest接受处理
3 指定DispatcherServlet<->Controller这两层控制器之间的关系:MappingHandler
注意,我们的二级控制器在rest-servlet.xml中,怎么被找到的呢?
原来,rest是一级控制器名称,那么,框架自动寻找 rest-servlet.xml,即 <一级控制器>-servlet.xml命名的xml文件自动被匹配。
注意,多个Handler时,order属性决定优先级,值越大,优先级越低。
4 加载二级控制器
5 加载viewResolver
Controller处理的结果返回时,需要viewResolver解析。注意,上面用了jstl渲染技术。容器自动查找 prefixValue + 视图逻辑名 + suffixValue