MVC 是 Xerox PARC 在 20 世纪 80 年代为编程语言 SmallTalk 发明的一种软件设计模式。
MVC 是一种设计模式,它强制性地把应用程序的数据展示、数据处理和流程控制分开。
MVC 将应用程序分成 3 个核心模块:模型、视图、控制器,他们相互联结又分别担当不同的任务,如图示所示。
☐ 模型:数据模型,提供要展示的数据,因此包含数据和行为,可以认为是 JavaBean,一个模型可以为多个视图提供数据。
☐ 视图:负责模型的展示,一般就是我们见到的用户界面,客户想要看到的东西。
☐ 控制器:控制器负责应用的流程控制,所谓流程控制就是接受用户请求,委托给模型进场处理,后获取模型数据交由视图展示。
说明
在早期的 web 应用中,JSP 负责处理业务逻辑、控制网页流程并创建 html 页面。基本上 JSP 包揽的所有的模块,这无疑造成了不少的困扰:
比如:
☐可维护性差
☐调试困难
☐ HTML 与 Java 程序代码强耦合在一起
☐ 内嵌的流程控制逻辑,要理解应用程序的逻辑必须浏览所有的 JSP 页面。
为了解决这些问题,SUN 公司先后制定了两种设计模式,分别为 Model1 和 Model2。虽然 Model1 在一定程序上实现了 MVC 中的视图和模型,但是他的运用并不理想,知道 Model2 的出现才改变了这种局面。
Model2 中用 JSP 技术实现了视图的功能、用 Servlet 技术实现了控制器的功能、用 JavaBean 技术实现了模型的功能。
图示
实例
说明
前端控制器 + 应用控制器 + 页面控制器 (也有称其为动作)+ 上下文,也是一种 WebMVC 模型,只是责任更加明确,SpringMVC 正是这种模式。
运行流程图
职责
Front Controller:前端控制器,负责为表现层提供统一访问点,从而避免 Model2 中出现的重复的控制逻辑(由前端控制器统一回调相应的功能方法,如前边的根据 submitFlag=login 转调 login 方法);并且可以为多个请求提供共用的逻辑(如准备上下文等等),将选择具体视图和具体的功能处理(如 login 里边封装请求参数到模型,并调用业务逻辑对象)分离。
Application Controller:应用控制器,前端控制器分离选择具体视图和具体的功能处理之后,需要有人来管理,应用控制器就是用来选择具体视图技术(视图的管理)和具体的功能处理(页面控制器 / 命令对象 / 动作管理),一种策略设计模式的应用,可以很容易的切换视图 / 页面控制器,相互不产生影响。
Page Controller(Command):页面控制器 / 动作 / 处理器:功能处理代码,收集参数、封装参数到模型,转调业务对象处理模型,返回逻辑视图名交给前端控制器(和具体的视图技术解耦),由前端控制器委托给应用控制器选择具体的视图来展示,可以是命令设计模式的实现。页面控制器也被称为处理器或动作。
Context:上下文,还记得 Model2 中为视图准备要展示的模型数据吗,我们直接放在 request 中(Servlet API 相关),有了上下文之后,我们就可以将相关数据放置在上下文,从而与协议无关(如 Servlet API)的访问 / 设置模型数据,一般通过 ThreadLocal 模式实现。
现在我们以前了解了 MVC 编程模型,接下来我们实际地编写一个 SpringMVC 入门实例,我们现在还不能解所有的技术细节,但是在接下来的博客一定会有相关解释。
- <?xml version="1.0" encoding="UTF-8" ?>
- <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">
- <!--配置DispatcherServlet-->
- <servlet>
- <servlet-name>
- dispatcherServlet
- </servlet-name>
- <servlet-class>
- org.springframework.web.servlet.DispatcherServlet
- </servlet-class>
- <!--配置初始化参数:作用是配置SpringMVC配置文件的位置和名称-->
- <init-param>
- <param-name>
- contextConfigLocation
- </param-name>
- <param-value>
- classpath:dispatcherServlet-servlet.xml
- </param-value>
- </init-param>
- <load-on-startup>
- 1
- </load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>
- dispatcherServlet
- </servlet-name>
- <url-pattern>
- /
- </url-pattern>
- </servlet-mapping>
- </web-app>
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
- <!--配置自动扫描的包-->
- <context:component-scan base-package="handles"/>
- <!--配置视图解析器:如何把handle方法返回值解析为实际的物理视图-->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/views/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
- </beans>
- /WEB-INF/views/success.jsp:
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>
- Title
- </title>
- </head>
- <body>
- Hello,World!
- </body>
- </html>
控制器 return 返回了视图的名称,我们在 SpringMVC 中设置了如何解析处理器返回值为视图。
所以当我们访问 / helloworld 后我们会被处理器跳转到 success.jsp 页面。
来源: http://www.cnblogs.com/MrSaver/p/6424291.html