在Web世界里,具体步骤以下:html
一、 Web浏览器(如IE)发起请求,如访问http://sishuok.com前端
二、 Web服务器(如Tomcat)接收请求,处理请求(好比用户新增,则将把用户保存一下),最后产生响应(通常为html)。java
三、web服务器处理完成后,返回内容给web客户端(通常就是咱们的浏览器),客户端对接收的内容进行处理(如web浏览器将会对接收到的html内容进行渲染以展现给客户)。web
所以,在Web世界里:apache
都是Web客户端发起请求,Web服务器接收、处理并产生响应。设计模式
通常Web服务器是不能主动通知Web客户端更新内容。虽然如今有些技术如服务器推(如Comet)、还有如今的HTML5 websocket能够实现Web服务器主动通知Web客户端。浏览器
到此咱们了解了在web开发时的请求/响应模型,接下来咱们看一下标准的MVC模型是什么。tomcat
MVC模型:是一种架构型的模式,自己不引入新功能,只是帮助咱们将开发的结构组织的更加合理,使展现与模型分离、流程控制逻辑、业务逻辑调用与展现逻辑分离。如图1-2服务器
图1-2websocket
首先让咱们了解下MVC(Model-View-Controller)三元组的概念:
Model(模型):数据模型,提供要展现的数据,所以包含数据和行为,能够认为是领域模型或JavaBean组件(包含数据和行为),不过如今通常都分离开来:Value Object(数据) 和 服务层(行为)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
View(视图):负责进行模型的展现,通常就是咱们见到的用户界面,客户想看到的东西。
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展现。 也就是说控制器作了个调度员的工做,。
从图1-1咱们还看到,在标准的MVC中模型能主动推数据给视图进行更新(观察者设计模式,在模型上注册视图,当模型更新时自动更新视图),但在Web开发中模型是没法主动推给视图(没法主动更新用户界面),由于在Web开发是请求-响应模型。
那接下来咱们看一下在Web里MVC是什么样子,咱们称其为 Web MVC 来区别标准的MVC。
模型-视图-控制器概念和标准MVC概念同样,请参考1.2,咱们再看一下Web MVC标准架构,如图1-3:
如图1-3
在Web MVC模式下,模型没法主动推数据给视图,若是用户想要视图更新,须要再发送一次请求(即请求-响应模型)。
概念差很少了,咱们接下来了解下Web端开发的发展历程,和使用代码来演示一下Web MVC是如何实现的,还有为何要使用MVC这个模式呢?
此处咱们只是简单的叙述比较核心的历程,如图1-4
图1-4
1.4.1、CGI:(Common Gateway Interface)公共网关接口,一种在web服务端使用的脚本技术,使用C或Perl语言编写,用于接收web用户请求并处理,最后动态产生响应给用户,但每次请求将产生一个进程,重量级。
1.4.2、Servlet:一种JavaEE web组件技术,是一种在服务器端执行的web组件,用于接收web用户请求并处理,最后动态产生响应给用户。但每次请求只产生一个线程(并且有线程池),轻量级。并且能利用许多JavaEE技术(如JDBC等)。本质就是在java代码里面 输出 html流。但表现逻辑、控制逻辑、业务逻辑调用混杂。如图1-5
图1-5
如图1-5,这种作法是绝对不可取的,控制逻辑、表现代码、业务逻辑对象调用混杂在一块儿,最大的问题是直接在Java代码里面输出Html,这样前端开发人员没法进行页面风格等的设计与修改,即便修改也是很麻烦,所以实际项目这种作法不可取。
1.4.3、JSP:(Java Server Page):一种在服务器端执行的web组件,是一种运行在标准的HTML页面中嵌入脚本语言(如今只支持Java)的模板页面技术。本质就是在html代码中嵌入java代码。JSP最终仍是会被编译为Servlet,只不过比纯Servlet开发页面更简单、方便。但表现逻辑、控制逻辑、业务逻辑调用仍是混杂。如图1-6
图1-6
如图1-6,这种作法也是绝对不可取的,控制逻辑、表现代码、业务逻辑对象调用混杂在一块儿,但比直接在servlet里输出html要好一点,前端开发人员能够进行简单的页面风格等的设计与修改(但若是嵌入的java脚本太多也是很难修改的),所以实际项目这种作法不可取。
JSP本质仍是Servlet,最终在运行时会生成一个Servlet(如tomcat,将在tomcat\work\Catalina\web应用名\org\apache\jsp下生成),但这种使得写html简单点,但还是控制逻辑、表现代码、业务逻辑对象调用混杂在一块儿。
1.4.4、Model1:能够认为是JSP的加强版,能够认为是jsp+javabean如图1-7
特色:使用<jsp:useBean>标准动做,自动将请求参数封装为JavaBean组件;还必须使用java脚本执行控制逻辑。
图1-7
此处咱们能够看出,使用<jsp:useBean>标准动做能够简化javabean的获取/建立,及将请求参数封装到javabean,再看一下Model1架构,如图1-8。
图1-8 Model1架构
Model1架构中,JSP负责控制逻辑、表现逻辑、业务对象(javabean)的调用,只是比纯JSP简化了获取请求参数和封装请求参数。一样是很差的,在项目中应该严禁使用(或最多再demo里使用)。
1.4.5、Model2:在JavaEE世界里,它能够认为就是Web MVC模型
Model2架构其实能够认为就是咱们所说的Web MVC模型,只是控制器采用Servlet、模型采用JavaBean、视图采用JSP,如图1-9
图1-9 Model2架构
具体代码事例以下:
从Model2架构能够看出,视图和模型分离了,控制逻辑和展现逻辑分离了。
但咱们也看到严重的缺点:
1. 一、控制器:
1.1.一、控制逻辑可能比较复杂,其实咱们能够按照规约,如请求参数submitFlag=toAdd,咱们其实能够直接调用toAdd方法,来简化控制逻辑;并且每一个模块基本须要一个控制器,形成控制逻辑可能很复杂;
1.1.二、请求参数到模型的封装比较麻烦,若是能交给框架来作这件事情,咱们能够从中获得解放;
1.1.三、选择下一个视图,严重依赖Servlet API,这样很难或基本不可能更换视图;
1.1.四、给视图传输要展现的模型数据,使用Servlet API,更换视图技术也要一块儿更换,很麻烦。
1.二、模型:
1.2.一、此处模型使用JavaBean,可能形成JavaBean组件类很庞大,通常如今项目都是采用三层架构,而不采用JavaBean。
1.三、视图
1.3.一、如今被绑定在JSP,很难更换视图,好比Velocity、FreeMarker;好比我要支持Excel、PDF视图等等。
1.4.5、服务到工做者:Front Controller + Application Controller + Page Controller + Context
即,前端控制器+应用控制器+页面控制器(也有称其为动做)+上下文,也是Web MVC,只是责任更加明确,详情请参考《核心J2EE设计模式》和《企业应用架构模式》如图1-10:
图1-10
运行流程以下:
职责:
Front Controller:前端控制器,负责为表现层提供统一访问点,从而避免Model2中出现的重复的控制逻辑(由前端控制器统一回调相应的功能方法,如前边的根据submitFlag=login转调login方法);而且能够为多个请求提供共用的逻辑(如准备上下文等等),将选择具体视图和具体的功能处理(如login里边封装请求参数到模型,并调用业务逻辑对象)分离。
Application Controller:应用控制器,前端控制器分离选择具体视图和具体的功能处理以后,须要有人来管理,应用控制器就是用来选择具体视图技术(视图的管理)和具体的功能处理(页面控制器/命令对象/动做管理),一种策略设计模式的应用,能够很容易的切换视图/页面控制器,相互不产生影响。
Page Controller(Command):页面控制器/动做/处理器:功能处理代码,收集参数、封装参数到模型,转调业务对象处理模型,返回逻辑视图名交给前端控制器(和具体的视图技术解耦),由前端控制器委托给应用控制器选择具体的视图来展现,能够是命令设计模式的实现。页面控制器也被称为处理器或动做。
Context:上下文,还记得Model2中为视图准备要展现的模型数据吗,咱们直接放在request中(Servlet API相关),有了上下文以后,咱们就能够将相关数据放置在上下文,从而与协议无关(如Servlet API)的访问/设置模型数据,通常经过ThreadLocal模式实现。
到此,咱们回顾了整个web开发架构的发展历程,可能不一样的web层框架在细节处理方面不一样,但的目的是同样的:
干净的web表现层:
模型和视图的分离;
控制器中的控制逻辑与功能处理分离(收集并封装参数到模型对象、业务对象调用);
控制器中的视图选择与具体视图技术分离。
轻薄的web表现层:
作的事情越少越好,薄薄的,不该该包含无关代码;
只负责收集并组织参数到模型对象,启动业务对象的调用;
控制器只返回逻辑视图名并由相应的应用控制器来选择具体使用的视图策略;
尽可能少使用框架特定API,保证容易测试。
到此咱们了解Web MVC的发展历程,接下来让咱们了解下Spring MVC究竟是什么、架构及来个HelloWorld了解下具体怎么使用吧。