SpringMVC
一、MVC
概述
- 数据模型层(model——JavaBean):实体类,负责数据逻辑的处理和在数据库中存取数据;
- 视图层(view——视图):数据展示、用户交互、数据验证、界面设计,负责格式化数据并呈现给用户;
- 控制层(controller——servlet):负责接收并转发视图,请求处理后,指定视图并将响应结果发送给客户端;
优缺点
优点
- 多视图共享一个模型,提高了代码的可重用性;
- MVC相互独立,松耦合架构;
- 控制器提高了程序的灵活性和可配置性;
- 有利于软件工程化管理;
缺点
- 原理复杂;
- 增加了系统结构和实现的复杂性;
- 视图对模型数据访问效率低;
注意
不介意中小型架构使用,配置繁琐
二、Spring MVC
概述
- Spring提供的一个基于MVC设计模式的轻量级web开发框架,本质上相当于servlet;
- 采用松耦合可插拔的组件结构,具有高度可配置性,比起其它MVC框架(Struts)更具有扩展性和灵活性;
- 支持注解驱动和REST风格;
优缺点
- 优点
- 清洗划分MVC三个角色,封装代码,维护成本低,耦合性低;
- 配置灵活(可以把类当作Bean通过XML进行配置),有利于开发中分工,提高开发效率;
- 提供了大量的控制器接口和实现类,组件重用、有利于代码复用,重用性高;
- 真正做到与view的实现无关(可以根据项目采取自己的视图框架,形如:jsp、Velocity、FreeMarker )
- 国际化编程,与Spring框架无缝集成,面向接口编程;
- 缺点
- 内部原理复杂,定义不明确;
- 不适合小型和中等规模的应用程序(形如:访问数据库的时候可以直接视图到模型,不需要控制层);
- 视图层与控制层过于紧密连接(形如:渲染视图需要经过控制层);
- 视图对模型数据的低效率访问(形如:当视图中的数据并没改变时,任要去访问对应模型获取数据再渲染);
- 优点
Spring MVC 和 Struts2
Spring MVC基于方法开发,Struts基于类开发。Spring MVC 优点是其所有请求参数都会被定义为相应方法的形参,用户在网页上的请求路径会被映射到 Controller 类对应的方法上,此时请求参数会注入到对应方法的形参上。而在使用 Struts2 框架进行开发时,Action 类中所有方法使用的请求参数都是 Action 类中的成员变量,随着方法变得越来越多,就很难分清楚 Action 中那么多的成员变量到底是给哪一个方法使用的,整个 Action 类会变得十分混乱。
Spring MVC可以进行单例开发,Struts无法使用单例(Struts2 由于只能通过类的成员变量接受参数,所以无法使用单例模式,只能使用多例);
Struts2 的处理速度要比 SpringMVC 慢,原因是 Struts2 使用了 Struts 标签,Struts 标签由于设计原因,会出现加载数据慢的情况;
三、执行流程
Spring MVC 涉及到的组件: DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、Handler(处理器,程序员编写的地方)、ViewResolver(视图解析器)和 View(视图)
| 组件 | 说明 |
|---|---|
| DispatcherServlet(前端控制器) | Spring MVC 的所有请求都要经过 DispatcherServlet 来统一分发。DispatcherServlet 相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。 |
| HandlerMapping(处理器映射器) | 根据请求的 URL 路径,通过注解或者 XML 配置,寻找匹配的处理器(Handler)信息 |
| HandlerAdapter(处理器适配器) | 根据映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler) |
| Handler(处理器) | 和 Java Servlet 扮演的角色一致。其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至 ModelAndView 对象中。 |
| ViewResolver(视图解析器) | 进行解析操作,通过 ModelAndView 对象中的 View 信息将逻辑视图名解析成真正的视图 View(如通过一个 JSP 路径返回一个真正的 JSP 页面) |
| View(视图) | 其本身是一个接口,实现类支持不同的 View 类型(JSP、FreeMarker、Excel 等) |
流程:
- 其本身是一个接口,实现类支持不同的 View 类型(JSP、FreeMarker、Excel 等);
- 由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain);
- DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
- HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller);
- Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息);
- HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
- DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
- ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet;
- DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
- 视图负责将结果显示到浏览器(客户端)。
四、视图解析器
视图解析器(ViewResolver):负责将逻辑视图名解析为具体的视图对象
Spring MVC提供的视图解析类:UrlBasedViewResolver、InternalResourceViewResolver 、FreeMarkerViewResolver
UrlBasedViewResolver
UrlBasedViewResolver 是对 ViewResolver 的一种简单实现,主要提供了一种拼接 URL 的方式来解析视图
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceViewResolver"/> <!--可以省略--> <!--前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean>注意:
- 通过 prefix 属性指定前缀,suffix 属性指定后缀。当 ModelAndView 对象返回具体的 View 名称时,它会将前缀 prefix 和后缀 suffix 与具体的视图名称拼接,得到一个视图资源文件的具体加载路径,从而加载真正的视图文件并反馈给用户;
- 上述视图解析器配置了前缀和后缀两个属性,这样缩短了 view 路径(形如:DispatcherServlet传递的view名为login,那么通过前缀和后缀拼接后的实际路径是 /WEB-INF/jsp/login.jsp ,而传递只需要传对应页面的名字即可);
- 存放在 /WEB-INF/ 目录下的内容不能直接通过 request 请求得到,所以为了安全性考虑,通常把 jsp 文件放在 WEB-INF 目录下
InternalResourceViewResolver
InternalResourceViewResolver 为“内部资源视图解析器”,是日常开发中最常用的视图解析器类型。它是 URLBasedViewResolver 的子类,拥有 URLBasedViewResolver 的一切特性。
FreeMarkerViewResolver
FreeMarkerViewResolver 是 UrlBasedViewResolver 的子类,可以通过 prefix 属性指定前缀,通过 suffix 属性指定后缀。
五、转发和重定向
转发
请求一次
重定向
请求两次