一、MVC 体系结构
1、MVC 三层架构
我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器;另一种是 B/S 架构 ,也就是浏览器服务器。
在 JavaEE 开发中,几乎全都是基于 B/S 架构的开发。
那么在 B/S 架构中,系统标准的三层架构包括:表现层、业务层、持久层。
三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于三层架构设计的。
三层架构中,每一层各司其职,接下来我们就说说每层都负责哪些方面:
1)表现层
也就是我们常说的 web 层。它负责接收客户端请求,向客户端响应结果,通常客户端使用 http 协议请求 web 层,web 需要接收 http 请求,完成 http 响应。
表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。
表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。
表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)。
2)业务层
也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。
web 层依赖业务层,但是业务层不依赖 web 层。
业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的,事务应该放到业务层来控制)。
3)持久层
也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。
通俗的讲,持久层就是和数据库交互,对数据库表进行增删改查的。
2、MVC 设计模式
MVC 全名是 Model View Controller,是 模型(model)- 视图(view)- 控制器(controller)的缩写,是一种用于设计创建 Web 应用程序表现层的模式。MVC 中每个部分各司其职:
- Model(模型):模型包含业务模型和数据模型,数据模型用于封装数据,业务模型用于处理业务。
- View(视图):通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。通常视图是依据模型数据创建的。
- Controller(控制器):是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。
MVC 提倡:每一层只编写自己的东⻄,不编写任何其他的代码;分层是为了解耦,解耦是为了维护方便和分工协作。
3、什么是 Spring MVC ?
SpringMVC 全名叫 Spring Web MVC,是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品。
Spring MVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring 3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。
servlet、struts 实现接口、springmvc 中要让一个 java 类能够处理请求只需要添加注解就 ok。
它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程⻛格的请求。
总之:Spring MVC 和 Struts2 一样,都是为了解决表现层问题的 web 框架,它们都是基于 MVC 设计模式的。而这些表现层框架的主要职责就是处理前端 HTTP 请求。
Spring MVC 本质可以认为是对 servlet 的封装,简化了我们 serlvet 的开发。
它的作用:
1)接收请求;
2)返回响应,跳转⻚面;
二、Spring Web MVC 工作流程
1、开发过程
需求:前端浏览器请求 url:http://localhost:8080/demo/handle01,前端⻚面显示后台服务器的时间。
1)配置 DispatcherServlet 前端控制器;
2)开发处理具体业务逻辑的 Handler(@Controller、@RequestMapping);
3)xml 配置文件配置 controller 扫描,配置 springmvc 三大件;
4)将 xml 文件路径告诉 springmvc(DispatcherServlet);
2、Spring MVC 请求处理流程
流程说明:
第一步:用户发送请求至前端控制器 DispatcherServlet;
第二步:DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器;
第三步:处理器映射器根据请求 Url 找到具体的 Handler(后端控制器),生成处理器对象及处理器拦截 器(如果有则生成)一并返回 DispatcherServlet;
第四步:DispatcherServlet 调用 HandlerAdapter 处理器适配器去调用 Handler;
第五步:处理器适配器执行 Handler;
第六步:Handler 执行完成给处理器适配器返回 ModelAndView;
第七步:处理器适配器向前端控制器返回 ModelAndView,ModelAndView 是 SpringMVC 框架的一个底层对象,包括 Model 和 View;
第八步:前端控制器请求视图解析器去进行视图解析,根据逻辑视图名来解析真正的视图;
第九步:视图解析器向前端控制器返回 View;
第十步:前端控制器进行视图渲染,就是将模型数据(在 ModelAndView 对象中)填充到 request 域;
第十一步:前端控制器向用户响应结果。
3、Spring MVC 九大组件
1)HandlerMapping(处理器映射器)
HandlerMapping 是用来查找 Handler 的,也就是处理器,具体的表现形式可以是类,也可以是方法。
比如,标注了 @RequestMapping 的每个方法都可以看成是一个 Handler。
Handler 负责具体实际的请求处理,在请求到达后,HandlerMapping 的作用便是找到请求相应的处理器 Handler 和 Interceptor。
2)HandlerAdapter(处理器适配器)
HandlerAdapter 是一个适配器。因为 Spring MVC 中 Handler 可以是任意形式的,只要能处理请求即可。但是把请求交给 Servlet 的时候,由于 Servlet 的方法结构都是 doService(HttpServletRequest req,HttpServletResponse resp) 形式的,要让固定的 Servlet 处理 方法调用 Handler 来进行处理,便是 HandlerAdapter 的职责。
3)HandlerExceptionResolver
HandlerExceptionResolver 用于处理 Handler 产生的异常情况。它的作用是根据异常设置 ModelAndView,之后交给渲染方法进行渲染,渲染方法会将 ModelAndView 渲染成⻚面。
4)ViewResolver
ViewResolver 即视图解析器,用于将 String 类型的视图名和 Locale 解析为 View 类型的视图,只有一个 resolveViewName() 方法。
从方法的定义可以看出,Controller 层返回的 String 类型视图名 viewName 最终会在这里被解析成为 View。
View 是用来渲染⻚面的,也就是说,它会将程序返回的参数和数据填入模板中,生成 html 文件。ViewResolver 在这个过程主要完成两件事情:ViewResolver 找到渲染所用的模板(第一件大事)和所用的技术(第二件大事,其实也就是找到视图的类型,如 JSP)并填入参数。
默认情况下,Spring MVC 会自动为我们配置一个 InternalResourceViewResolver,是针对 JSP 类型视图的。
5)RequestToViewNameTranslator
RequestToViewNameTranslator 组件的作用是从请求中获取 ViewName。因为 ViewResolver 根据 ViewName 查找 View,但有的 Handler 处理完成之后,没有设置 View,也没有设置 ViewName, 便要通过这个组件从请求中查找 ViewName。
6)LocaleResolver
ViewResolver 组件的 resolveViewName 方法需要两个参数,一个是视图名,一个是 Locale。
LocaleResolver 用于从请求中解析出 Locale,比如中国 Locale 是 zh-CN,用来表示一个区域。这个组件也是 i18n 的基础。
7)ThemeResolver
ThemeResolver 组件是用来解析主题的。主题是样式、图片及它们所形成的显示效果的集合。
Spring MVC 中一套主题对应一个 properties 文件,里面存放着与当前主题相关的所有资源,如图片、CSS 样式等。
创建主题非常简单,只需准备好资源,然后新建一个 “主题名.properties” 并将资源设置进去,放在 classpath 下,之后便可以在⻚面中使用了。
SpringMVC 中与主题相关的类有 ThemeResolver、ThemeSource 和 Theme。
ThemeResolver 负责从请求中解析出主题名,ThemeSource 根据主题名找到具体的主题,其抽象也就是 Theme,可以通过 Theme 来获取主题和具体的资源。
8)MultipartResolver
MultipartResolver 用于上传请求,通过将普通的请求包装成 MultipartHttpServletRequest 来实现。MultipartHttpServletRequest 可以通过 getFile() 方法直接获得文件。
如果上传多个文件,还可以调用 getFileMap() 方法得到 Map<FileName,File> 这样的结构,MultipartResolver 的作用就是封装普通的请求,使其拥有文件上传的功能。
9)FlashMapManager
FlashMap 用于重定向时的参数传递,比如在处理用户订单时候,为了避免重复提交,可以处理完 post 请求之后重定向到一个 get 请求,这个 get 请求可以用来显示订单详情之类的信息。
这样做虽然可以规避用户重新提交订单的问题,但是在这个⻚面上要显示订单的信息,这些数据从哪里来获得呢?因为重定向时没有传递参数这一功能的,如果不想把参数写进URL(不推荐),那么就可以通过 FlashMap 来传递。
只需要在重定向之前将要传递的数据写入请求(可以通过 ServletRequestAttributes.getRequest() 方法获得)的属性 OUTPUT_FLASH_MAP_ATTRIBUTE 中,这样在重定向之后的 Handler 中 Spring 就会自动将其设置到 Model 中,在显示订单信息的⻚面上就可以直接从 Model 中获取数据。
FlashMapManager 就是用来管理 FalshMap 的。
文章内容输出来源:拉勾教育Java高薪训练营;