SpringMVC1️⃣MVC、入门、原理
1、MVC
1.1、说明
MVC 设计模式,用于应用程序的分层开发。
- Model(模型):提供数据(DAO、VO)和业务逻辑(Service)
- View(视图):负责数据的可视化,即模型的展示。
- Controller(控制器)
- 接收视图层的用户请求,调度(Dispatcher)给模型进行处理。
- 将处理返回的数据渲染视图。
1.2、发展
Model 1
早期 Web 开发,
分为视图层和模型层。
-
优点:架构简单。
-
缺点:模型层职责不单一(展示数据 + 接收处理请求)
Model 2
将项目分为 M-V-C 三层,即目前的 MVC 模式。
职责分明,利于维护
-
Controller:接收请求、调用业务逻辑、响应页面(跳转)
-
Model:处理业务逻辑(Service)、保存数据状态(DAO)
-
View:显示页面
2、Spring MVC
全称
Spring Web MVC
(👉 官方文档)基于 Java Servlet API,实现 MVC 设计模式的轻量级 Web 框架。
- 核心:围绕
DispatcherServlet
设计,将请求分发到不同的处理器。 - 特点:
- 轻量级,简洁灵活,简单易学。
- 高效,基于请求响应的 MVC 框架。
- 与 Spiring 兼容性好,无缝结合。
- 约定大于配置。
- 功能强大:RESTful、数据验证、格式化、本地化、主题等。
2.1、对比
传统 web 开发中,通常每个业务对应一个 Servlet,项目臃肿。
Spring MVC:将 Servlet 的共性行为和特有行为分离
-
DispatcherServlet:抽取并封装共性行为,将请求分发到不同的处理器(也称前端控制器)
-
处理器(handler):负责处理业务,通常是编写 Controller 作为处理器(也称后端控制器)
2.2、开发步骤(❗)
2.2.1、环境搭建
-
添加 web 框架支持、集成 Tomcat
-
导入依赖:直接导入 webmvc 依赖,会自动导入相关的 spring 依赖
<dependency> <groupId>org.springframework</groupId> <artifactId >spring-webmvc</artifactId> <version>5.3.9</version> </dependency>
2.2.2、配置(❗)
SpringMVC 核心配置文件
-
SpringMVC 的配置与 Spring 分开编写,且通常命名
spring-mvc.xml
-
开启注解扫描
<context:component-scan base-package="indi.jaywee.controller"/>
配置 DispathcerServlet:在
web.xml
中
-
关联核心配置文件
-
启动时加载
-
映射地址(类似 Java Web 中 Filter 的匹配规则)
-
匹配形式:精确(
/xxx
)、后缀(*.xxx
)、通配(/
) -
通常使用后缀匹配或通配的形式
-
不能使用
/*
,否则会拦截返回的 JSP 视图。<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:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
2.2.3、Controller & JSP
-
创建 success.jsp 页面
-
创建 Controller:基于注解配置 Controller 和 URL 映射
@Controller public class HelloController { @RequestMapping("/hello") public String hello() { System.out.println("hello"); return "success.jsp"; } }
-
测试
2.2.4、报错 4xx 或 5xx(❗)
若所有步骤都正确,但是报错 4xx 或 5xx,检查 Tomcat 打包路径。
-
项目结构 → Artifacts → 当前模块 → WEB-INF
-
查看有无 lib 目录,没有则手动创建并添加 jar 包
3、Spring MVC 原理
3.1、@RequestMapping
作用:建立请求的 URL 与处理器之间的映射关系。
3.1.1、使用位置
两级目录共同组成请求 URL 的虚拟路径
- 类上:请求 URL 的第一级访问目录(可选)
- 方法上:请求 URL 的第二级访问目录
示例:访问 URL 为 http://localhost:8080/上下文路径/user/add
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/add")
public void addUser(User user) {...}
}
3.1.2、常用属性
-
value:指定请求 URL
-
method:指定请求方式(可选,不指定则任何请求方式都可访问)
-
RequestMethod
枚举类中封装了可指定的请求方式类型。 -
可使用具体请求方式的注解:
@GetMapping
、@PostMapping
等(本质也是@RequestMapping
)
-
示例
-
任意请求方式
// 任意请求方式 @RequestMapping("/add") public void addUser(User user) {...} // 相当于 @RequestMapping(value = "/add") public void addUser(User user) {...}
-
指定请求方式
// 指定请求方式 @RequestMapping(value = "/add", method = RequestMethod.GET) public void addUser(User user) {...} // 相当于 @GetMapping("/add") public void addUser(User user) {...}
3.2、执行流程(❗)
3.2.1、组件
整个执行流程中,主要涉及以下组件。
含义 | 功能 | 说明 | |
---|---|---|---|
DispatcherServlet | 前端控制器 | 拦截前端请求,调度各组件 | 相当于 MVC 中的 C |
HandlerMapping | 处理器映射器 | 负责解析请求所对应的处理器,返回处理器执行链 | 根据 XML 配置或注解进行解析查找 |
HandlerExecutionChain | 处理器执行链 | 包含处理器对象和处理器拦截器 | 责任链模式(类似 Filter 中的过滤器链) |
HandlerAdapter | 处理器适配器 | 调度具体的处理器 | 适配器 |
Handler | 处理器 | 真正处理具体请求,响应 ModelAndView | 即 Controller,也称后端控制器 |
ModelAndView | 模型视图 | 封装了数据和视图 | |
ViewResolver | 视图解析器 | 根据 ModelAndView,解析视图对象 |
3.2.2、流程图
Tomcat 引擎接收客户端请求,封装 request 和 response 对象。
DispatcherServlet 的执行操作:
-
调用
HandlerMapping
解析请求对应的资源,获得HandlerExecutionChain
。 -
调用
HandlerAdapter
,将请求调度给具体的Handler
处理,获得ModelAndView
。 -
调用
ViewResolver
,解析ModelAndView
得到View
。 -
渲染视图,向客户端发送响应。
3.3、组件配置
- 在 SpringMVC 中,DispatcherServlet 配置了默认组件。
- 运用了 策略模式,各个组件可以相互替换。
3.3.1、默认组件
查看 spring-webmvc.jar
源码中的 DispatcherServlet.properties
3.3.2、视图解析器
InternalResourceViewResolver
(默认视图解析器)
有参构造方法:调用了父类的 setPrefix()
和 setSuffix()
父类
UrlBasedViewResolver
-
属性
-
请求和重定向前缀:用于判断 controller 指定跳转的视图名中,是否指定请求或重定向类型
-
URL 前缀和后缀:默认为空串,支持自定义
public static final String REDIRECT_URL_PREFIX = "redirect:"; public static final String FORWARD_URL_PREFIX = "forward:"; private String prefix = ""; private String suffix = "";
-
-
方法(针对以上 4 个属性,其它的不作展示)
createView()
:判断视图名中是否指定请求或重定向类型,创建相应的 URL。setPrefix()
、setSuffix()
:根据 SpringMVC 核心配置文件的配置,设置指定的前缀和后缀。
3.3.3、自定义视图前后缀
在(前后端不分离)开发中,很少修改其它组件配置(使用默认的即可)。
通常会配置视图解析器。
-
在
spring-mvc.xml
中配置视图解析器,自定义前后缀。 -
controller 在指定视图名时,视图解析器会自动拼接指定的前后缀。
-
注:prefix 值的前面必须加
/
,否则报错。<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/前缀"/> <property name="suffix" value="后缀"/> </bean>
示例
指定拼接方式:/user/视图名.jsp
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/user/"/>
<property name="suffix" value=".jsp"/>
</bean>
Controller:返回的视图只需指定页面名称,无需编写前后缀
@Controller
public class RouterController {
@RequestMapping("/toLogin")
public String toLogin() {
return "login";
}
@RequestMapping("/toRegister")
public String toRegister() {
return "register";
}
}