1.1 分层设计
在大型软件系统设计时,业务一般会相对复杂,假如所有业务实现的代码都纠缠在一起,会出现逻辑不清晰、可读性差,维护困难,改动一处就牵一发而动全身等问题。为了更好解决这个问题就有了我们现在常说的分层架构设计。
**分层设计的本质其实就是将复杂问题简单化,首先基于单一职责原则(SRP-Single responsibility principle)让每个对象各司其职,各尽所能。然后再基于"高内聚,低耦合"的设计思想实现相关层对象之间的交互。这样可以更好提高程序的可维护性和可扩展性,**例如生活中的楼宇设计,生日蛋糕设计,企业的组织架构设计等。
1.2 MVC设计思想
MVC(Model--view--controller)是软件工程中的一种软件架构模式,基于此模式把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。目的是通过这样的设计使程序结构更加简洁、直观,降低问题的复杂度。其中MVC各个组成部分为:
-
视图(View)- UI设计人员进行图形界面设计,负责实现与用户交互。
-
控制器(Controller)- 负责获取请求,处理请求,响应结果。
-
模型(Model) - 实现业务逻辑,数据逻辑实现。
思考:海底捞中的MVC?(菜单-View,服务员-Controller,厨师-Model)
1.3 JavaEE组件应用中的MVC设计
在JavaEE技术体系中,基于MVC设计思想,各个核心组件的应用关系如图所示:
在上图中,Servlet充当MVC中的Controller,负责调用model处理业务,负责转换或重定向某个页面,在页面上呈现数据。
1.4 Spring框架中Web模块的MVC设计
Spring MVC 是Spring 框架中基于MVC设计思想,实现的一个用于处理Web请求的模块。这个模块封装了对Servlet的技术的应用,简化了程序员对请求和响应过程中数据的处理,其简易架构分析如图所示:
图中,核心组件分析:
-
DispatcherServlet:前端控制器,不需要工程师开发,由框架提供
作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求
-
HandlerMapping:处理器映射器,不需要工程师开发,由框架提供
作用:根据请求的url、method等信息查找Handler,即控制器方法
-
Handler:处理器,需要工程师开发
作用:在DispatcherServlet的控制下Handler对具体的用户请求进行处理
-
HandlerAdapter:处理器适配器,不需要工程师开发,由框架提供
作用:通过HandlerAdapter对处理器(控制器方法)进行执行
-
HandlerInterceptor:拦截器, 需要工程师开发
作用:实现请求响应的共性处理
-
ViewResolver:视图解析器(前缀+viewname+后缀),不需要工程师开发,由框架提供
作用:进行视图解析,得到相应的视图,例如:ThymeleafView、InternalResourceView、RedirectView
-
View:视图
作用:将模型数据通过页面展示给用户。
2 整合SpringMVC快速入门
2.1 初始配置
-
第一步:创建Maven项目 , 名为JSDVNxxxx , 并创建Spring Boot子项目 , 名为SpringMVC
-
添加Spring Web依赖(提供了Spring MVC依赖支持),这个依赖添加时,会关联下载一个Tomcat依赖(一个嵌入式Tomcat服务器),代码如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> -
第二步:添加Thymeleaf依赖,Thymeleaf为一个模板引擎,它以html页面为模板,通过解析html来呈现服务端返回的数据。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
Thymeleaf是一个模板引擎,能够处理HTML、XML、JavaScript、CSS甚至纯文本。能轻易的与Spring MVC等Web框架进行集成。 与其它模板引擎相比,Thymeleaf最大的特点是能够直接在浏览器中打开,并正确显示模板页面,而不需要启动整个Web应用(更加方便前后端分离,比如方便类似VUE前端设计页面)。现在,Thymeleaf也是Spring Boot官方的推荐使用模板。
- 第三步:配置Spring MVC视图前缀后缀。
在application.properties文件中添加视图解析器配置。
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
说明:在SpringBoot 工程下,假如配置文件中没有配置视图前缀,默认为/templates/, 后缀默认为.html。
2.2 快速入门实践
-
第一步:编写HelloController类并将其交给Spring管理。
package com.spring.controller;
@Controller //标识此类为controller,并创建对象交给Spring容器管理
public class HelloController {
} -
第二步:在HelloController中添加方法,代码如下。
其中:@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。
**@RequestMapping标识一个类:**设置映射请求的请求路径的初始信息。
**@RequestMapping标识一个方法:**设置映射请求的请求路径的具体信息。
@RequestMapping("/hello") //定义访问路径
public String doHelloUI() {
//返回给调用方,这里是DispatcherServlet,DispatcherServlet会将hello字符串交给视图解析器,thymeleaf中的视图解析器会对hello字符串添加前缀和后缀
return "hello";
}
}@RequestMapping("/doSayHello")
@ResponseBody //告诉SpringMVC框架返回值不是view,而是具体的数据
public String doSayHello() {
return "hello spring mvc";
}
其中 :
-
doHelloUI方法返回值hello, 为一个view的名称,这个名字会返回给Spring MVC框架中的DispatcherServlet对象(前端控制器),此对象会调用视图解析器对象对view名称进行解析,构建一个具体的view对象。最后将此view响应到客户端。
-
doSayHello方法返回值为一个hello spring mvc字符串,这个字符串会直接响应到客户端,因为方法上有一个@ResponseBody注解。这个注解描述方法时,用于告诉Spring MVC,方法的返回值不是view,假如是字符串则直接响应到客户端,假如是pojo对象则转换为json格式字符串响应到客户端。
-
第三步:在/templates/目录(这个目录为视图解析器的前缀)下创建hello.html页面,代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body>The HelloPage
</body> </html> -
第四步:启动Web服务器(默认项目嵌入的是tomcat),打开浏览器分别输入http://localhost:8080/hello,http://localhost:8080/doSayHello进行访问测试。
2.3 运行过程BUG分析
- 端口号被占用 , 如下图所示 :
解决方案 :
- 关闭已启动的Tomcat服务 , 然后重新启动
- 杀进程(windows) 查找进程id:netstat -ano|findstr "8080" , 基于进程id杀进程: taskkill /f /pid 进程id
- URL响应资源不存在 , 如下图所示 :
解决方案 :
- 检查Tomcat服务器是否启动成功
- 检查url对应的服务端资源是否匹配(客户端url与controller定义url)
- 检查controller的包结构(所在包应在主启动类所在包的同包或子包中)
- 视图解析失败 , 如下图所示 :
解决方案 :
检查配置文件中视图解析器的配置是否有正确
总结 :
重难点分析 :
- DispatcherServlet , HandlerMapping , Controller , ViewResolver等组件作用 , 并描述SpringMVC运行流程
- Spring Web依赖及Thymeleaf依赖作用
- @Controller , @RequestMapping , @ResponseBody等注解如何使用及作用
SpringMVC运行流程详解图 :