SpringMVC 初识
SpringMVC 概述
SpringMVC 是隶属于 Spring 框架的一部分,主要是用来进行 Web 开发,是对 Servlet 进行了封装。
不难看出 MVC 对应的就是三层架构
我们先来回顾下现在 web 程序是如何做的,咱们现在 web 程序大都基于三层架构来实现。
浏览器发送一个请求给后端服务器,后端服务器现在是使用 Servlet 来接收请求和数据
如果所有的处理都交给 Servlet 来处理的话,所有的东西都耦合在一起,对后期的维护和扩展极为不利
将后端服务器 Servlet 拆分成三层,分别是
web
、service
和dao
web 层主要由 servlet 来处理,负责页面请求和数据的收集以及响应结果给前端
service 层主要负责业务逻辑的处理
dao 层主要负责数据的增删改查操作
servlet 处理请求和数据的时候,存在的问题是一个 servlet 只能处理一个请求
针对 web 层进行了优化,采用了 MVC 设计模式,将其设计为
controller
、view
和Model
controller 负责请求和数据的接收,接收后将其转发给 service 进行业务处理
service 根据需要会调用 dao 对数据进行增删改查
dao 把数据处理完后将结果交给 service,service 再交给 controller
controller 根据需求组装成 Model 和 View,Model 和 View 组合起来生成页面转发给前端浏览器
这样做的好处就是 controller 可以处理多个请求,并对请求进行分发,执行不同的业务操作。
随着互联网的发展,上面的模式因为是同步调用,性能慢慢的跟不是需求,所以异步调用慢慢的走到了前台,是现在比较流行的一种处理方式。
因为是异步调用,所以后端不需要返回 view 视图,将其去除
前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成 json 格式进行返回
SpringMVC==主要==负责的就是
controller 如何接收请求和数据
如何将请求和数据转发给业务层
如何将响应数据转换成 json 发回到前端
我们也可以这么表示后端的三层服务架构:
我们的数据层本来是使用 JDBC 技术,现在可以被 Mybatis 框架取代我们的表现层本来是使用 Servlet 技术,现在可以使用 SpringMVC 替代
介绍了这么多,对 SpringMVC 进行一个定义
SpringMVC 是一种基于 Java 实现 MVC 模型的轻量级 Web 框架
优点
使用简单、开发便捷(相比于 Servlet)
灵活性强
我们可以简单地从代码量上去体会他的强大,实现相同的功能:
不使用 SpringMVC 框架:
使用 SpringMVC 框架:
SpringMVC 入门案例
因为 SpringMVC 是一个 Web 框架,将来是要替换 Servlet,所以先来回顾下以前
Servlet 是如何进行开发的?
1.创建 web 工程(Maven 结构)
2.设置 tomcat 服务器,加载 web 工程(tomcat 插件)
3.导入坐标(Servlet)
4.定义处理请求的功能类(UserServlet)
5.设置请求映射(配置映射关系)
SpringMVC 的制作过程和上述流程几乎是一致的,具体的实现流程是什么?
1.创建 web 工程(Maven 结构)
2.设置 tomcat 服务器,加载 web 工程(tomcat 插件)
3.导入坐标(SpringMVC+Servlet)
4.定义处理请求的功能类(UserController)
5.设置请求映射(配置映射关系)
6.将 SpringMVC 设定加载到 Tomcat 容器中
步骤实现
步骤 1:首先创建一个 maven 项目步骤 2:补全目录结构步骤 3:导入 jar 包:
说明:servlet 的坐标为什么需要添加<scope>provided</scope>
?
scope 是 maven 中 jar 包依赖作用范围的描述,
如果不设置默认是
compile
在在编译、运行、测试时均有效如果运行有效的话就会和 tomcat 中的 servlet-api 包发生冲突,导致启动报错
provided 代表的是该包只在编译和测试的时候用,运行的时候无效直接使用 tomcat 中的,就避免冲突
步骤 4:创建配置类
步骤 5:创建 Controller 类
步骤 6:使用配置类替换 web.xml
将 web.xml 删除,换成 ServletContainersInitConfig
==配置完这些之后如果直接使用 tomcat 运行时会报错的==,因为后台没有指定返回的页面(但是我们可以在控制台看到user save ...
)
我们可以修改 Controller 返回值解决上述问题:
前面我们说过现在主要的是前端发送异步请求,后台响应 json 数据,所以接下来我们把 Controller 类的 save 方法进行修改
再次重启 tomcat 服务器,然后重新通过浏览器测试访问,会发现还是会报错,这次的错是 404。出错的原因是,如果方法直接返回字符串,springmvc 会把字符串当成页面的名称在项目中进行查找返回,因为不存在对应返回值名称的页面,所以会报 404 错误,找不到资源。
而我们其实是想要直接返回的是 json 数据,具体如何修改呢?
那么设置返回数据为 json:
再次运行 tomcat:
成功!
案例注意点
注意事项:
SpringMVC 是基于 Spring 的,在 pom.xml 只导入了
spring-webmvc
jar 包的原因是它会自动依赖 spring 相关坐标AbstractDispatcherServletInitializer 类是 SpringMVC 提供的快速初始化 Web3.0 容器的抽象类
AbstractDispatcherServletInitializer 提供了三个接口方法供用户实现
createServletApplicationContext 方法,创建 Servlet 容器时,加载 SpringMVC 对应的 bean 并放入 WebApplicationContext 对象范围中,而 WebApplicationContext 的作用范围为 ServletContext 范围,即整个 web 容器范围
getServletMappings 方法,设定 SpringMVC 对应的请求映射路径,即 SpringMVC 拦截哪些请求
createRootApplicationContext 方法,如果创建 Servlet 容器时需要加载非 SpringMVC 对应的 bean,使用当前方法进行,使用方式和 createServletApplicationContext 相同。
createServletApplicationContext 用来加载 SpringMVC 环境
createRootApplicationContext 用来加载 Spring 环境
案例总结
其实这个案例基本就涉及四个步骤:步骤一:
步骤二:
步骤三:
步骤四:
知识点 1:@Controller
知识点 2:@RequestMapping
知识点 3:@ResponseBody
我们在上面案例中的操作,有的以后我们可能不需要再重复:
一次性工作
创建工程,设置服务器,加载工程
导入坐标
创建 web 容器启动类,加载 SpringMVC 配置,并设置 SpringMVC 请求拦截路径
SpringMVC 核心配置类(设置配置类,扫描 controller 包,加载 Controller 控制器 bean)
多次工作
定义处理请求的控制器类
定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回 json 数据(@ResponseBody)
案例工作流程解析
为了更好的使用 SpringMVC,我们将 SpringMVC 的使用过程总共分两个阶段来分析,分别是启动服务器初始化过程
和单次请求过程
:
启动服务器初始化过程
服务器启动,执行 ServletContainersInitConfig 类,初始化 web 容器
功能类似于以前的 web.xml
执行 createServletApplicationContext 方法,创建了 WebApplicationContext 对象
该方法加载 SpringMVC 的配置类 SpringMvcConfig 来初始化 SpringMVC 的容器
加载 SpringMvcConfig 配置类
执行 @ComponentScan 加载对应的 bean
扫描指定包及其子包下所有类上的注解,如 Controller 类上的 @Controller 注解
加载 UserController,每个 @RequestMapping 的名称对应一个具体的方法
此时就建立了
/save
和 save 方法的对应关系执行 getServletMappings 方法,设定 SpringMVC 拦截请求的路径规则
/
代表所拦截请求的路径规则,只有被拦截后才能交给 SpringMVC 来处理请求
单次请求过程
发送请求
http://localhost/save
web 容器发现该请求满足 SpringMVC 拦截规则,将请求交给 SpringMVC 处理
解析请求路径/save
由/save 匹配执行对应的方法 save()
上面的第五步已经将请求路径和方法建立了对应关系,通过/save 就能找到对应的 save 方法
执行 save()
检测到有 @ResponseBody 直接将 save()方法的返回值作为响应体返回给请求方
版权声明: 本文为 InfoQ 作者【十八岁讨厌编程】的原创文章。
原文链接:【http://xie.infoq.cn/article/9bba8ec1fdd5125ff5ba30cc8】。未经作者许可,禁止转载。
评论