??欢迎来到@的csdn博文??
??本文主要梳理SpringMVC : 基于 Spring 的 Web 层MVC 框架??
??喜欢的朋友可以关注一下**???**,下次更新不迷路??
Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)???
目录
[??MVC 的工作流程](#??MVC 的工作流程)
[??MVC 的优点](#??MVC 的优点)
[??MVC 的不足](#??MVC 的不足)
[??Spring MVC:构建强大的Web应用程序](#??Spring MVC:构建强大的Web应用程序)
[??什么是Spring MVC?](#??什么是Spring MVC?)
[??Spring MVC的工作原理](#??Spring MVC的工作原理)
[??Spring MVC 的常用组件](#??Spring MVC 的常用组件)
??@Controller和@RequestMapping注解
[??@Controller 注解](#??@Controller 注解)
[??@RequestMapping 注解](#??@RequestMapping 注解)
[??@RequestMapping 注解的使用方式](#??@RequestMapping 注解的使用方式)
[??@RequestMapping 注解的属性](#??@RequestMapping 注解的属性)
[??支持 Ant 风格的路径](#??支持 Ant 风格的路径)
C语言中文网:C语言程序设计门户网站(入门教程、编程软件) (biancheng.net) 学习笔记
??MVC模式
MVC 模式,全称为 Model-View-Controller(模型-视图-控制器)模式,它是一种软件架构模式,其目标是将软件的用户界面(即前台页面)和业务逻辑分离,使代码具有更高的可扩展性、可复用性、可维护性以及灵活性。
MVC 模式将应用程序划分成模型(Model)、视图(View)、控制器(Controller)等三层,如下图所示。
分层
描述
Model(模型)
它是应用程序的主体部分,主要由以下2 部分组成:
- 实体类 Bean:专门用来存储业务数据的对象,它们通常与数据库中的某个表对应,例如 User、Student等。
- 业务处理 Bean:指 Service 或 Dao 的对象,专门用于处理业务逻辑、数据库访问。
一个模型可以为多个视图(View)提供数据,一套模型(Model)的代码只需写一次就可以被多个视图重用,有效地减少了代码的重复性,增加了代码的可复用性。
View(视图)
指在应用程序中专门用来与浏览器进行交互,展示数据的资源。在 Web 应用中,View 就是我们常说的前台页面,通常由HTML、JSP、CSS、JavaScript 等组成。
Controller(控制器)
通常指的是,应用程序的 Servlet。它负责将用户的请求交给模型(Model)层进行处理,并将Model 层处理完成的数据,返回给视图(View)渲染并展示给用户。
在这个过程中,Controller 层不会做任何业务处理,它只是 View(视图)层和 Model (模型)层连接的枢纽,负责调度 View 层和 Model 层,将用户界面和业务逻辑合理的组织在一起,起粘合剂的效果。
??MVC 的工作流程
MVC 的工作流程如下:
- 用户发送请求到服务器;
- 在服务器中,请求被控制层(Controller)接收;
- Controller 调用相应的 Model 层处理请求;
- Model 层处理完毕将结果返回到 Controller;
- Controller 再根据 Model 返回的请求处理结果,找到相应的 View 视图;
- View 视图渲染数据后最终响应给浏览器。
??MVC 的优点
MVC 模式具有以下优点:
- 降低代码耦合性:在 MVC 模式中,三层之间相互独立,各司其职。一旦某一层的需求发生了变化,我们就只需要更改相应层中的代码即可,而不会对其他层中的代码造成影响。
- 有利于分工合作:在 MVC 模式中,将应用系统划分成了三个不同的层次,可以更好地实现开发分工。例如,网页设计人员专注于视图(View)层的开发,而那些对业务熟悉的开发人员对Model 层进行开发,其他对业务不熟悉的开发人员则可以对Controller 层进行开发。
- 有利于组件的重用:在 MVC 中,多个视图(View)可以共享同一个模型(Model),大大提高了系统中代码的可重用性。
??MVC 的不足
MVC 模式存在以下不足之处:
-
增加了系统结构和实现的复杂性:对于简单的应用,如果也严格遵循 MVC 模式,按照模型、视图与控制器对系统进行划分,无疑会增加系统结构的复杂性,并可能产生过多的更新操作,降低运行效率。
-
视图与控制器间的联系过于紧密:虽然视图与控制器是相互分离的,但它们之间联系却是十分紧密的。视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了它们的独立重用。
-
视图对模型数据的低效率访问:视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。
MVC 并不适合小型甚至中型规模的项目,花费大量时间将 MVC 应用到规模并不是很大的应用程序中,通常会得不偿失,因此对于 MVC 设计模式的使用要根据具体的应用场景来决定。
??Spring MVC:构建强大的Web应用程序
Spring MVC(Model-View-Controller)是Java世界中最流行的Web应用程序开发框架之一。它提供了一种结构化的方法 来构建强大的Web应用程序,使开发人员能够轻松管理请求和响应 、处理表单提交、进行验证以及与数据库进行交互。本文将深入探讨Spring MVC的核心概念和工作原理,帮助你更好地理解并利用这个强大的框架来构建Web应用程序。
??什么是Spring MVC?
Spring MVC(全称 Spring Web MVC)是 Spring 框架提供的一款基于 MVC 模式的轻量级 Web 开发框架,是 Spring 为表示层(UI)开发提供的一整套完备的解决方案。
-
表示层(UI):用来实现与用户的交互,接收用户请求,并将请求交给业务逻辑层(BLL)和数据访问层(DAL)进行处理,最后将处理结果返回给用户。
-
业务逻辑层(BLL):起到承上启下的作用,接收表示层传递来的请求,并针对业务对数据进行处理,以实现业务目标。
-
数据访问层(DAL):用于实现与数据库的交互和访问,例如从数据库中获取数据、保存或修改数据库中的数据等。
Spring MVC 使用 MVC 架构模式的思想,将 Web 应用进行职责解构,把一个复杂的 Web 应用划分成模型(Model)、控制器(Contorller)以及视图(View)三层,有效地简化了 Web 应用的开发,降低了出错风险,同时也方便了开发人员之间的分工配合。
Spring MVC 各层的职责如下:
- Model:负责对请求进行处理,并将结果返回给 Controller;
- View:负责将请求的处理结果进行渲染,展示在客户端浏览器上;
- Controller:是 Model 和 View 交互的纽带;主要负责接收用户请求,并调用 Model 对请求处理,然后将 Model 的处理结果传递给 View。
Spring MVC 本质是对 Servlet 的进一步封装,其最核心的组件是 DispatcherServlet,它是 Spring MVC 的前端控制器,主要负责对请求和响应的统一地处理和分发。Controller 接收到的请求其实就是 DispatcherServlet 根据一定的规则分发给它的。
Spring MVC 框架内部采用松耦合、可插拔的组件结构,具有高度可配置性,比起其他的 MVC 框架更具有扩展性和灵活性。此外,Spring MVC 的注解驱动(annotation-driven)和对 REST 风格的支持,也是它最具有特色的功能。
Spring MVC 是 Spring 框架的众多子项目之一,自 Spring 框架诞生之日起就包含在 Spring 框架中了,它可以与 Spring 框架无缝集成,在性能方面具有先天的优越性。对于开发者来说,Spring MVC 的开发效率要明显高于其它的 Web 框架,因此 Spring MVC 在企业中得到了广泛的应用,成为目前业界最主流的 MVC 框架之一。
??SpringMVC的特征
1. SpringMVC 从易用性,效率上 比曾经流行的 Struts2 更好
2. SpringMVC 是 WEB 层框架【解读 : SpringMVC 接管了 Web 层组件 , 比如控制器 , 视 图 , 视图解析 , 返回给用户的数据格式 , 同时支持 MVC 的开发模式/开发架构(使用了web就会有) 】
3. SpringMVC 通过注解,让 POJO 成为控制器,不需要继承类或者实现接口
4. SpringMVC 采用低耦合的组件设计方式,具有更好扩展和灵活性 .
5. 支持 REST 格式的 URL 请求 .
6. SpringMVC 是基于 Spring 的 , 也就是 SpringMVC 是在 Spring 基础上的。 SpringMVC 的核 心包 spring-webmvc-xx.jar 和 spring-web-xx.jar
梳理 Spring SpringMVC SpringBoot 的关系
1. Spring MVC 只是 Spring 处理 WEB 层请求的一个模块 / 组件 , Spring MVC 的基石是 Servlet[Java WEB]
2. Spring Boot 是为了简化开发者的使用 , 推出的封神框架 ( 约定优于配置,简化了 Spring 的配置流程 ), SpringBoot 包含很多组件 / 框架,
Spring 就是最核心的内容之一,也包含 Spring MVC
3. 他们的关系大概是**: Spring Boot > Spring > Spring MVC**
??Spring MVC的工作原理
Spring MVC的工作原理可以分为以下几个步骤:
-
用户发送请求 :当用户在浏览器中输入URL或单击链接时,请求被发送到Web应用程序的前端控制器(通常是
DispatcherServlet
)。 -
DispatcherServlet处理请求 :
DispatcherServlet
是Spring MVC的核心,它接收所有请求并负责将请求分派给适当的控制器。控制器的选择是基于请求的URL映射。 -
控制器处理请求 :选定的控制器(通常是一个带有
@Controller
注解的Spring组件)接收请求,并根据业务逻辑处理它。控制器可以访问模型、调用服务、验证数据等。 -
控制器返回模型和视图 :控制器处理请求后,它通常会返回一个模型(数据)和一个视图名称。模型包含要呈现给视图的数据。视图名称告诉
DispatcherServlet
要使用哪个视图来渲染响应。 -
视图呈现响应 :
DispatcherServlet
使用视图解析器来将视图名称解析为实际的视图对象(例如JSP或Thymeleaf模板)。视图使用模型中的数据来渲染响应,然后将其发送回客户端。
??SpringMVC工作流程
Spring MVC 工作流程
SpringMVC 的执行流程如下。
- 用户通过浏览器发起一个 HTTP 请求,该请求会被DispatcherServlet(前端控制器)拦截;
- DispatcherServlet 调用 HandlerMapping(处理器映射器)找到具体的处理器(Handler)及拦截器,最后以HandlerExecutionChain执行链的形式返回给 DispatcherServlet。
- DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
- HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(即 Controller 控制器)对请求进行处理;
- Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC 的底层对象,包括 Model 数据模型和 View 视图信息);
- HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
- DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
- ViewResolver 解析完成后,会将 View 视图并返回给 DispatcherServlet;
- DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
- 视图负责将结果显示到浏览器(客户端)。
??Spring MVC 的常用组件
Spring MVC 的常用组件如下表。
组件
提供者
描述
DispatcherServlet
框架提供
前端控制器,它是整个 Spring MVC 流程控制中心,负责统一处理请求和响应,调用其他组件对用户请求进行处理。
HandlerMapping
框架提供
处理器映射器,根据请求的 url、method 等信息查找相应的 Handler。
Handler
开发人员提供
处理器,通常被称为Controller(控制器)。它可以在 DispatcherServlet 的控制下,对具体的用户请求进行处理。
HandlerAdapter
框架提供
处理器适配器,负责调用具体的控制器方法,对用户发来的请求来进行处理。
ViewResolver
框架提供
视图解析器,其职责是对视图进行解析,得到相应的视图对象。常见的视图解析器有 ThymeleafViewResolver、InternalResourceViewResolver 等。
View
开发人员提供
视图,它作用是将模型(Model)数据通过页面展示给用户。
??@Controller和@RequestMapping注解
从 Java 5 开始,Java 就增加了对注解(Annotation)的支持,它是代码中的一种特殊标记 ,**可以在编译、加载和运行时被读取,执行相应的处理。**通过注解,开发人员可以在不改变原有代码逻辑的情况下,在代码中嵌入补充信息。
**Spring 从 2.5 版本开始提供了对注解技术的全面支持,以替换传统的 XML 配置,简化 Spring 的配置。**作为 Spring 框架的一个子项目, Spring MVC 自然也提供了对注解的支持。
在 Spring MVC 中有两个十分重要的注解,它们分别是 @Controller 和 @RequestMapping 。本节,我们就针对这两个重要 Spring MVC 注解进行讲解。
??@Controller 注解
@Controller 注解可以将一个普通的 Java 类标识成控制器(Controller)类,示例代码如下。
package net.biancheng.controller;
import org.springframework.stereotype.Controller;
@Controller
public class IndexController {
// 处理请求的方法
}
Spring MVC 是通过组件扫描机制查找应用中的控制器类的,为了保证控制器能够被 Spring MVC 扫描到,我们还需要在 Spring MVC 的配置文件中使用<context:component-scan/>
标签,指定控制器类的基本包(请确保所有控制器类都在基本包及其子包下),示例代码如下。
<!-- 使用扫描机制扫描控制器类,控制器类都在net.biancheng.controller包及其子包下 -->
<context:component-scan base-package="net.biancheng.controller" />
??@RequestMapping 注解
@RequestMapping 注解是 Spring MVC 中最常被用到的注解之一。它通常被标注在控制器方法上,负责将请求与处理请求的控制器方法关联起来,建立映射关系。
Spring MVC 的前端控制器(DispatcherServlet)拦截到用户发来的请求后,会通过 @RequestMapping 注解提供的映射信息找到对应的控制器方法,对这个请求进行处理。
??@RequestMapping 注解的使用方式
@RequestMapping 既可以标注在控制器类上,也可以标注在控制器方法上。
1. 修饰方法
当 @RequestMapping 注解被标注在方法上时,value 属性值就表示访问该方法的 URL 地址。当用户发送过来的请求想要访问该 Controller 下的控制器方法时,请求路径就必须与这个 value 值相同,示例代码如下。
@Controller
public class HelloController {
@RequestMapping("/login")
public String welcome() {
return "login";
}
}
2. 修饰类
当@RequestMapping 注解标注在控制器类上时 ,value 属性的取值就是这个控制器类中的所有控制器方法 URL 地址的父路径 。也就是说,访问这个 Controller 下的任意控制器方法都需要带上这个父路径。
@Controller
@RequestMapping(value = "/springmvc")
public class HelloController {
@RequestMapping("/login")
public String welcome() {
return "login";
}
}
例如,在上面的控制类中,用户想要访问 HelloController 中的 welcome() 方法,请求的地址就必须带上父路径"/springmvc",即请求地址必须为"/springmvc/login"。
??@RequestMapping 注解的属性
@RequestMapping 注解中提供了多个可用属性,下面我们就对其中几个比较常用的属性进行介绍。
??1. value 属性
在 @RequestMapping 注解中,value 属性用来设置控制器方法的请求映射地址。所有能够匹配到该请求映射地址的请求,都可以被该控制器方法处理,示例代码如下。
@RequestMapping(value = "/register")
value 属性是@RequestMapping 注解的默认属性,如果我们在 @RequestMapping 注解中只设置了一个 value 属性,则该属性名可以被省略,示例代码如下。
//省略 value 属性名
@RequestMapping( "/register")
value 属性的取值是一个字符串类型的数组,表示该控制器方法可以匹配多个请求地址。
@RequestMapping( value = {"/register", "/login"})
public String success() {
return "success";
}
??2. name 属性
name 属性相当于方法的注释,用于解释这个方法是用来干什么的,使方法更易理解。
例如,下面的代码表示 getUsers() 方法是一个用来获取用户信息的控制器方法。
@RequestMapping(value = "toUser",name = "获取用户信息")
public String getUsers() {
......
}
??3. method 属性
method 属性用来设置控制器方法支持的请求方式。如果一个控制器方法没有设置 @RequestMapping 注解的 method 属性,则说明该控制器方法支持全部请求类型,可以处理所有类型的请求。
method 属性的取值是一个 RequestMethod 类型的数组,表示一个控制器方法支持多种方式的请求,常用的请求方式有GET、POST、DELETE、PUT 等。
例如,控制器方法只支持 GET 方式的请求,代码如下。
@RequestMapping(value = "/toUser",method = RequestMethod.GET)
我们也可以为同一个控制器方法指定支持多种类型的请求。例如,一个方法既支持 GET 方式的请求,也支持 POST 方式的请求,代码如下。
@RequestMapping(value = "/toUser",method = {RequestMethod.GET,RequestMethod.POST}),
??4. params 属性
params 属性用于指定请求中的参数,只有当请求中携带了符合条件的参数时,控制器方法才会对该请求进行处理。
我们可以通过以下 4 种表达式来对请求的参数进行配置。
序号
表达式
含义
①
"param"
请求中必须携带名为 param 的参数
②
"!param"
与表达式 ①的含义完全相反,请求中不能携带名为 param的参数
③
"param=value"
请求中必须携带名为 param 的参数,且参数的取值必须为:value
④
"param!=value"
与表达式 ③ 的含义完全相反,请求中不能携带参数:param = value。
params 属性的取值是一个字符串类型的数组,表示只有请求中同时携带了 params 属性指定的全部参数时,控制器方法才会对该请求进行处理。
例如,控制器方法 testParam() 的代码如下:
@RequestMapping(value = "/testParam", params = {"name=C语言中文网", "url=http://c.bianheng.net"})
@ResponseBody
public String testParam() {
return "success";
}
以上代码表示,只有当请求中同时携带 name 和 url 两个请求参数,且参数值必须分别为 "C语言中文网" 和"http://c.biancheng.net"时,控制器方法 testParam() 才会对该请求进行处理 。
??5. headers 属性
headers 属性用于设置请求中请求头信息,只有当请求中携带指定的请求头信息时,控制器方法才会处理该请求。
我们可以通过以下 4 种表达式来指定请求中的请求头信息。
序号
表达式
含义
①
"header"
请求必须携带请求头信息:header
②
"!header"
与表达式 ①的含义完全相反,请求中不能携带请求头信息:header
③
"header=value"
请求中必须携带请求头信息:header=value。
④
"header!=value"
与表达式 ③ 的含义完全相反,请求中不能携带请求头信息:header=value。
header 属性是一个字符串类型的数组,表示只有当请求同时携带数组中规定的所有头信息时,控制器方法才会对该请求进行处理。
例如,控制器方法 method() 的代码如下。
@RequestMapping(value = "toUser",headers = "Referer=http://c.biancheng.net")
public String metnod() {
......
}
在以上代码中,只有当请求的头信息中包含"Referer=http://c.biancheng.net"时,控制器方法 method() 才会处理该请求。
??支持 Ant 风格的路径
Spring MVC 还提供了对 Ant 风格路径的支持,我们可以在 @RequestMapping 注解的 value 属性中使用 Ant 风格的统配符,来设置请求映射地址。
常用的 Ant 风格的通配符,如下表所示。
通配符
说明
请求映射举例
匹配的请求地址举例
表示任意的单个字符。
@RequestMapping(value = "/test-user")
- localhost:8080/test-userA
- localhost:8080/test-userb
- localhost:8080/test-user1
*
表示任意的 0 个或多个字符。
@RequestMapping(value = "/test-user*")
- localhost:8080/test-user
- localhost:8080/test-userA
- localhost:8080/test-user-abc
**
表示任意的一层或多层目录。
注意,在使用该通配符时,其使用方式只能时 "/**/xxx"。
@RequestMapping(value = "/**/testuser")
- localhost:8080/test-user
- localhost:8080/aa/test-user
- localhost:8080/aa/bb/test-user
???