Spring MVC快速入门
1. Spring MVC 概述
Spring MVC 是什么?
Spring MVC 是目前实现 MVC 设计模式最好的框架,是 Spring 全家桶的一个分支产品,以 Spring IOC 容器为基础,并利用容器的特性来简化它的配置。Spring MVC 相当于 Spring 的一个子模块,可以很好的和 Spring 结合起来进行开发,是 JavaWeb 开发者必须要掌握的框架。
什么是 MVC 设计模式?
Spring MVC 实现了 MVC 设计模式,MVC 设计模式是一种常用的软件架构方式:以 Controller(控制层)、Model(模型层)、View(视图层) 三个模块分离的形式来组织代码。
MVC流程:视图层与客户端的用户进行交互并捕获用户请求,控制层接收到客户端请求后,调用模型层的业务方法生成模型数据,然后通过控制层传递到视图层,最终将业务数据和视图响应给客户端浏览器渲染展示。
- 视图层:负责 Web 应用程序对用户的展示,它从用户那里获取输入数据,并通过控制层传给模型层处理,然后再通过控制层获取模型层返回的模型数据并显示给用户。
- 控制层:负责控制应用程序的流程,它接收从视图层传过来的数据,它接收从视图层传过来的数据,然后选择模型层中的某个业务逻辑来处理,接收模型层返回的结果并选择视图层中的某个视图来显示,是人机交互与数据库操作的中介。
- 模型层:负责实现应用程序的业务逻辑,与数据库进行交互,封装有各种对数据的处理的业务方法。它不关心会如何被视图层渲染或被控制器调用,它只根据业务要求查询数据库,然后封装成 Java 对象返回。
Spring MVC 就是对这套流程的封装,屏蔽了很多的底层代码,开放出接口,让开发者可以更加轻松快捷的完成基于 MVC 模式的 Web 开发。
2. SpringMVC 架构原理
SpringMVC 的核心组件:
-
DispatcherServlet:前端控制器,是整个流程控制的核心,控制其他组件的执行,统一调度,降低组件之间的耦合性,相当于总指挥;
-
HandlerMapping:DispatcherServlet 接收到请求之后,通过 HandlerMapping 将不同的请求映射到不同的 Handler;
-
Handler:处理器,完成具体的业务逻辑,相当于 JavaEE 里面的 Servlet 或 Action;
-
HandlerInterceptor:处理拦截器,是一个接口,如果需要完成一些拦截处理(拦截请求或响应),可以实现该接口;
-
HandlerExecutionChain:处理器执行链,包括两个部分的内容:Handler 和 HandlerInterceptor(系统会会有一个默认的 HandlerInterceptor,如果需要额外设置拦截,可以添加拦截器);
-
HandlerAdapter:处理器适配器,Handler 执行业务方法之前,需要进行一系列的操作,包括表单数据的验证、数据类型的转换、将表单数据封装到 JavaBean 等,这些操作都是由 HandlerAdapter 来完成,开发者只需要将注意力集中业务逻辑的处理上,DispatcherServlet 通过 HandlerAdapter 执行不同的 Handler;
-
ModelAndView:装载了模型数据和视图信息,作为 Handler 的处理结果,返回给 DispatcherServlet;
-
ViewResolver:视图解析器,DispatcherServlet 通过它将逻辑视图解析为物理视图,读取 Web 容器中的物理文件,将最终的渲染结果响应给客户端。
以上是 SpringMVC 的核心组件,那么这些组件之间是如何进行交互的呢?
Spring MVC 的工作流程:
- 客户端请求被 DispatcherServlet 接收;
- 根据 handlerMapping 映射到 Handler;
- 生成的 Handler 和 HandlerInterceptor(如果有则生成);
- Handler 和 HandlerInterceptor 以 HandlerExecutionChian 的形式一并返回给 DispatcherServlet;
- DispatcherServlet 通过 HandlerAdapter 通过 Handler 的方法做业务逻辑处理;
- 返回一个 ModelAndView 对象给 DispatcherServlet ;
- DispatcherServlet 将获取的 ModelAndView 对象传给 ViewResolver 视图解析器,将逻辑视图解析成物理视图 View;
- ViewResolver 返回一个 View 给 DispatcherServlet;
- DispatcherServlet 根据 View 进行视图渲染(将模型数据填充到视图中);
- DispatcherServlet 将渲染后的视图响应给客户端;
3. 如何使用 Spring MVC?
SpringMVC 如此众多的组件结合起来看似非常复杂,但是实际开发中是很简单的,因为大部分的组件都由框架提供,作为开发者直接使用即可,并不需要自己手动编写代码,真正需要开发者进行编写的组件只有三个:① 配置 SpringMVC 组件;② Handler:处理业务逻辑 ;③ View:JSP做页面展示。
第一步:创建 maven 工程,并在 pom.xml 文件中添加 SpringMVC 相关的依赖;
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
</dependencies>
可以看到,我们在添加 SpringMVC 的 maven 依赖时,自动会把 Spring 相关的底层依赖(beans、core、aop等)添加进来,这也说明了 SpringMVC 是基于 Spring 框架的组件,是不能单独存在的。
第二步:在 WEB-INF/web.xml 中配置 DispatcherServlet 组件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!-- 捕获所有请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
注:在 JavaEE 中配置 Servlet 的方式有两种,第一种是通过 XML 的方式来配置,另外一种则是通过注解的方式添加 @WebServlet
,但这里的 DispatcherServlet 组件是由 SpringMVC 提供的(org.springframework.web.servlet.DispatcherServlet
),所以开发者不能在源码中手动的添加注解,故只能通过 XML 的方式配置。
第三步:创建 JavaWeb 的工程目录,并添加 springmvc.xml 到 resources 配置文件
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 自动扫描 -->
<context:component-scan base-package="com.trainingl.handler"></context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
- 自动扫描的类结合注解交给 IOC 容器管理
- 视图解析器是 SpringMVC 底层的组件,开发者只需要进行配置即可完成 JSP 页面的跳转,如何配置很简单:目标资源路径 = 前缀 + 逻辑视图 + 后缀,比如 DispatcherServlet 返回视图文件名 index,配置文件中前缀是/,后缀是.jsp,则目标资源路径就是:
/index.jsp
,即:webapp文件下的 index.jsp 文件。
第四步:创建 HelloHandler 处理器
package com.trainingl.handler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloHandler {
@RequestMapping("/index")
public String test(){
System.out.println("执行了index方法...");
//返回的是逻辑视图
return "index";
}
}
直接在业务方法处添加注解 @RequestMapping("/index")
,将 URL 请求 index 直接与业务方法映射,既直观又方便。
第五步:配置 Tomcat 服务器,启动 JavaWeb 的测试环境
将 springmvcPro:war
工程打包,然后启动 Tomcat 服务器
浏览器的测试结果如下:
我们重新来回顾一下整个 SpringMVC 的处理流程:
- DispatcherServlet 接收到浏览器地址栏的 URL 请求
/index
,结合@RequestMapping("/index")
注解映射到对应的业务方法来处理; - 执行 test 业务方法,控制台打印日志信息,并返回 “index” 字符串;
- 结合 springmvc.xml 中的视图解析器配置,找到目标资源:
/index.jsp
,即根目录webapp下的 index.jsp,将该 jsp 资源返回到客户端完成响应。
至此,SpringMVC 环境搭建完成!