【Spring MVC】快速学习使用Spring MVC的注解及三层架构



💓 博客主页:从零开始的-CodeNinja之路
⏩ 收录文章:【Spring MVC】快速学习使用Spring MVC的注解及三层架构
🎉欢迎大家点赞👍评论📝收藏⭐文章
目录
- Spring Web MVC
- 一: 什么是Spring Web MVC?
- 二:Spring MVC中常用注解的使用
- 2.1 @RequestMapping:地址映射
- 2.2 @RequestBody:请求正文
- 2.3 @PathVariable:路径变量
- 2.4 @RequestPart:上传文件
- 2.5 @RequestParam:重命名
- 2.6 @RestController:数据控制器
- 2.7 @ResponseBody:数据格式
- 2.8 @CookieValue:获取Cookie
- 2.9 @SessionAttribute:获取Session
- 2.10 @Data:类注解
- 三:应用分层-三层架构
- 四:总结
Spring Web MVC
一: 什么是Spring Web MVC?
SpringWebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中。它的正式名称“SpringWebMVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为)SpringMVC).
MVC是⼀种架构设计模式,也⼀种思想,⽽SpringMVC是对MVC思想的具体实现.除此之外,SpringMVC还是⼀个Web框架.
总结来说,SpringMVC是⼀个实现了MVC模式的Web框架
MVC的定义
MVC是ModelViewController的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分
为模型、视图和控制器三个基本部分

• View(视图)指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.
• Model(模型)是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.
• Controller(控制器)可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型
来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型
二:Spring MVC中常用注解的使用
2.1 @RequestMapping:地址映射
@RequestMapping既可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类路径+⽅
法路径.
@RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息
@RequestMapping标识⼀个⽅法:设置映射请求请求路径的具体信息
@RequestMapping("/user")
@RestController
public class UserController {@RequestMapping("/sayHi")public String sayHi(){return "hello,Spring MVC";}
}
2.2 @RequestBody:请求正文
RequestBody:请求正⽂,意思是这个注解作⽤在请求正⽂的数据绑定,请求参数必须在写在请求正
⽂中
@RequestMapping(value = "/m7")
public Object method7(@RequestBody Person person) {return person.toString();
}
2.3 @PathVariable:路径变量
pathvariable:路径变量
和字⾯表达的意思⼀样,这个注解主要作⽤在请求URL路径上的数据绑定
默认传递参数写在URL上,SpringMVC就可以获取到
后端实现代码:
@RequestMapping("/m8/{id}/{name}")
public String method8(@PathVariable Integer id, @PathVariable("name") StringuserName){return "解析参数id:"+id+",name:"+userName;
}
如果⽅法参数名称和需要绑定的URL中的变量名称⼀致时,可以简写,不⽤给@PathVariable的属性赋
值,如上述例⼦中的id变量
如果⽅法参数名称和需要绑定的URL中的变量名称不⼀致时,需要@PathVariable的属性value赋值,
如上述例⼦中的userName变量
2.4 @RequestPart:上传文件
RequestPart主要是用于客户端上传文件交给服务器进行处理
后端代码实现:
@RequestMapping("/m9")
public String getfile(@RequestPart("file") MultipartFile file) throwsIOException {//获取⽂件名称String fileName = file.getOriginalFilename();//⽂件上传到指定路径file.transferTo(new File("D:/temp/" + file.getOriginalFilename()));return "接收到⽂件名称为: "+fileName;
}
2.5 @RequestParam:重命名
某些特殊的情况下,前端传递的参数key和我们后端接收的key可以不⼀致,⽐如前端传递了⼀个
time给后端,⽽后端是使⽤createtime字段来接收的,这样就会出现参数接收不到的情况,如果出现
这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值
后端实现代码:
@RequestMapping("/m4")
public Object method_4(@RequestParam("time") String createtime) {return "接收到参数createtime:" + createtime;
}
可以得出结论:
- 使⽤ @RequestParam 进⾏参数重命名时,请求参数只能和 @RequestParam 声明的名称⼀
致,才能进⾏参数绑定和赋值. - 使⽤ @RequestParam 进⾏参数重命名时,参数就变成了必传参数.
2.6 @RestController:数据控制器
是Contronller和ResponseBody的封装,用于返回数据同时能够将注解内容交给Spring进行管理
@RestController = @Controller + @ResponseBody
@Controller :定义⼀个控制器,Spring框架启动时加载,把这个对象交给Spring管理.
@ResponseBody :定义返回的数据格式为⾮视图,返回⼀个text/html信息
2.7 @ResponseBody:数据格式
@ResponseBody :定义返回的数据格式为⾮视图,返回⼀个text/html信息
@ResponseBody
public class IndexController {@RequestMapping("/index")public Object index(){return "/index.html";}
}
@ResponseBody 既是类注解,⼜是⽅法注解
如果作⽤在类上,表⽰该类的所有⽅法,返回的都是数据,如果作⽤在⽅法上,表⽰该⽅法返回的是数据.
也就是说:在类上添加 @ResponseBody 就相当于在所有的⽅法上添加了 @ResponseBody 注解.
同样,如果类上有 @RestController 注解时:表⽰所有的⽅法上添加了 @ResponseBody 注
解,也就是当前类下所有的⽅法返回值做为响应数据
设置状态码
SpringMVC会根据我们⽅法的返回结果⾃动设置响应状态码,程序员也可以⼿动指定状态码
通过SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置
@ResponseBodypublic String setStatus(HttpServletResponse response) {response.setStatus(401);return "设置状态码成功";}
2.8 @CookieValue:获取Cookie
Cook是用户客户端用于保存用户的基本信息,以便于用户在下一次登录时可以直接进入

@RequestMapping("/getCookie")
public String cookie(@CookieValue("bite") String bite) {return "bite:" + bite;
}
2.9 @SessionAttribute:获取Session
Session是服务器为了保存⽤⼾信息⽽创建的⼀个特殊的对象

Session的本质就是⼀个"哈希表",存储了⼀些键值对结构.Key就是SessionID,Value就是⽤⼾信息(⽤
⼾信息可以根据需求灵活设计).
SessionId是由服务器⽣成的⼀个"唯⼀性字符串",从Session机制的⻆度来看,这个唯⼀性字符串称
为)SessionId).但是站在整个登录流程中看待,也可以把这个唯⼀性字符串称为)token).

- 当⽤⼾登陆的时候,服务器在Session中新增⼀个新记录,并把sessionId返回给客⼾端.(通过
HTTP响应中的Set-Cookie字段返回). - 客⼾端后续再给服务器发送请求的时候,需要在请求中带上sessionId.(通过HTTP请求中的
Cookie字段带上). - 服务器收到请求之后,根据请求中的sessionId在Session信息中获取到对应的⽤⼾信息,再进⾏后
续操作.找不到则重新创建Session,并把SessionID返回
@RequestMapping("/getSess2")
public String sess2(@SessionAttribute(value = "username",required = false)String username) {return "username:"+username;
}
Cookie和Session的区别
• Cookie是客⼾端保存⽤⼾信息的⼀种机制.Session是服务器端保存⽤⼾信息的⼀种机制.
• Cookie和Session之间主要是通过SessionId关联起来的,SessionId是Cookie和Session之间的
桥梁
• Cookie和Session经常会在⼀起配合使⽤.但是不是必须配合.
◦ 完全可以⽤Cookie来保存⼀些数据在客⼾端.这些数据不⼀定是⽤⼾⾝份信息,也不⼀定是
SessionId
◦ Session中的sessionId也不需要⾮得通过Cookie/Set-Cookie传递,⽐如通过URL传递.
2.10 @Data:类注解
Lombok是⼀个Java⼯具库,通过添加注解的⽅式,简化Java的开发其中@Data 注解会帮助我们⾃动⼀些⽅法,包含getter/setter,equals,toString等
Lombok的作⽤如下图所⽰:

如果觉得@Data⽐较粗暴(⽣成⽅法太多),lombok也提供了⼀些更精细粒度的注解
| 注解 | 作⽤ |
|---|---|
| @Getter | ⾃动添加getter⽅法 |
| @Setter | ⾃动添加setter⽅法 |
| @ToString | ⾃动添加toString⽅法 |
| @EqualsAndHashCode | ⾃动添加equals和hashCode⽅法 |
| @NoArgsConstructor | ⾃动添加⽆参构造⽅法 |
| @AllArgsConstructor | ⾃动添加全属性构造⽅法,顺序按照属性的定义顺序 |
| @NonNull | 属性不能为null |
| @RequiredArgsConstructor | ⾃动添加必需属性的构造⽅法,final+@NonNull的属性为必需 |
@Data=@Getter+@Setter+@ToString+@EqualsAndHashCode+@RequiredArgsConstructor+@NoArgsConstructor
因此可以说明在创建类对象时可以通过引入lambok工具包中的@Data注解,可以自动为我们添加其很多常用的赋值方法
三:应用分层-三层架构
⽬前现在更主流的开发⽅式是"前后端分离"的⽅式,后端开发⼯程师不再需要关注前端的实现,所以对
于Java后端开发者,⼜有了⼀种新的分层架构:把整体架构分为表现层、业务逻辑层和数据层.这种分层
⽅式也称之为"三层架构".
- 表现层:就是展⽰数据结果和接受⽤⼾指令的,是最靠近⽤⼾的⼀层;
- 业务逻辑层:负责处理业务逻辑,⾥⾯有复杂业务的具体实现;
- 数据层:负责存储和管理与应⽤程序相关的数据
可以看到,咱们前⾯的代码,并不符合这种设计思想,⽽是所有的代码堆砌在⼀起
按照上⾯的层次划分,SpringMVC站在后端开发⼈员的⻆度上,也进⾏了⽀持,
• 请求处理、响应数据:负责,接收⻚⾯的请求,给⻚⾯响应数据.
• 逻辑处理:负责业务逻辑处理的代码.
• 数据访问:负责业务数据的维护操作,包括增、删、改、查等操作

• Controller:控制层。接收前端发送的请求,对请求进⾏处理,并响应数据。
• Service:业务逻辑层。处理具体的业务逻辑。
• Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查
MVC和三层架构的区别和联系
关于⼆者的关系,⼀直存在不同的观点.有⼈认为三层架构是MVC模式的⼀种实现,也有⼈认为MVC是
三层架构的替代⽅案,等等各种说法都有.根本原因是⼤家站在不同的⻆度来看待这个问题的.
JavaEE部分的学习重在"实践",⼤家根据⾃⼰的理解,能够⾃圆其说,说出⾃⼰的观点即可,也不建议
⼤家去背书.
从概念上来讲,⼆者都是软件⼯程领域中的架构模式.
MVC架构模式由三部分组成,分别是:模型(Model),视图(View)和控制器(Controller).
三层架构将业务应⽤划分为:表现层,业务逻辑层,数据访问层.

MVC中,视图和控制器合起来对应三层架构中的表现层.模型对应三层架构中的业务逻辑层,数据层,
以及实体类
⼆者其实是从不同⻆度对软件⼯程进⾏了抽象.
MVC模式强调数据和视图分离,将数据展⽰和数据处理分开,通过控制器对两者进⾏组合.
三层架构强调不同维度数据处理的⾼内聚和低耦合,将交互界⾯,业务处理和数据库操作的逻辑分开.
⻆度不同也就谈不上互相替代了,在⽇常的开发中可以经常看到两种共存的情况,⽐如我们设计模型
层的时候往往也会拆分出业务逻辑层(Service层)和数据访问层(Dao层)
四:总结
1.学习SpringMVC,其实就是学习各种Web开发需要⽤的到注解
a. @RequestMapping:路由映射
b. @RequestParam:后端参数重命名
c. @RequestBody:接收JSON类型的参数
d. @PathVariable:接收路径参数
e. @RequestPart:上传⽂件
f. @ResponseBody:返回数据
g. @CookieValue:从Cookie中获取值
h. @SessionAttribute:从Session中获取值
i. @RequestHeader:从Header中获取值
j. @Controller:定义⼀个控制器,Spring框架启动时加载,把这个对象交给Spring管理.默认返回
视图.
k. @RestController:@ResponseBody+@Controller返回数据
2. Cookie和Session都是会话机制,Cookie是客⼾端机制,Session是服务端机制.⼆者通过SessionId
来关联.SpringMVC内置HttpServletRequest,HttpServletResponse两个对象.需要使⽤时,直接在
⽅法中添加对应参数即可,Cookie和Session可以从HttpServletRequest中来获取,也可以直接使⽤
HttpServletResponse设置Http响应状态码.
相关文章:
【Spring MVC】快速学习使用Spring MVC的注解及三层架构
💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:【Spring MVC】快速学习使用Spring MVC的注解及三层架构 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 Spring Web MVC一: 什么是Spring Web MVC࿱…...
Python(乱学)
字典在转化为其他类型时,会出现是否舍弃value的操作,只有在转化为字符串的时候才不会舍弃value 注释的快捷键是ctrl/ 字符串无法与整数,浮点数,等用加号完成拼接 5不入??? 还有一种格式化的方法…...
OpenHarmony实战:轻量级系统之子系统移植概述
OpenHarmony系统功能按照“系统 > 子系统 > 部件”逐级展开,支持根据实际需求裁剪某些非必要的部件,本文以部分子系统、部件为例进行介绍。若想使用OpenHarmony系统的能力,需要对相应子系统进行适配。 OpenHarmony芯片适配常见子系统列…...
Neo4j基础知识
图数据库简介 图数据库是基于数学里图论的思想和算法而实现的高效处理复杂关系网络的新型数据库系统。它善于高效处理大量的、复杂的、互连的、多变的数据。其计算效率远远高于传统的关系型数据库。 在图形数据库当中,每个节点代表一个对象,节点之间的…...
HTTP/1.1 特性(计算机网络)
HTTP/1.1 的优点有哪些? 「简单、灵活和易于扩展、应用广泛和跨平台」 1. 简单 HTTP 基本的报文格式就是 header body,头部信息也是 key-value 简单文本的形式,易于理解。 2. 灵活和易于扩展 HTTP 协议里的各类请求方法、URI/URL、状态码…...
每日一题————P5725 【深基4.习8】求三角形
题目: 题目乍一看非常的简单,属于初学者都会的问题——————————但是实际上呢,有一些小小的坑在里面。 就是三角形的打印。 平常我们在写代码的时候,遇到打印三角形的题,一般简简单单两个for循环搞定 #inclu…...
第三题:时间加法
题目描述 现在时间是 a 点 b 分,请问 t 分钟后,是几点几分? 输入描述 输入的第一行包含一个整数 a。 第二行包含一个整数 b。 第三行包含一个整数 t。 其中,0≤a≤23,0≤b≤59,0≤t, 分钟后还是在当天。 输出描…...
【RAG】内部外挂知识库搭建-本地GPT
大半年的项目告一段落了,现在自己找找感兴趣的东西学习下,看看可不可以搞出个效果不错的local GPT,自研下大模型吧 RAG是什么? 检索增强生成(RAG)是指对大型语言模型输出进行优化,使其能够在生成响应之前引用训练数据来…...
MySQL——锁
全局锁 全局锁是一种数据库锁定机制,它可以锁定整个数据库,阻止其他会话对数据库的读写操作。在MySQL中,全局锁定可以使用FLUSH TABLES WITH READ LOCK命令来实现。执行这个命令后,MySQL将获取一个全局读锁,直到当前会…...
C++(12): std::mutex及其高级变种的使用
1. 简述 在多线程或其他许多场景下,同时对一个变量或一段资源进行读写操作是一个比较常见的过程,保证数据的一致性和防止竞态条件至关重要。 C的标准库中为我们提供了使用的互斥及锁对象,帮助我们实现资源的互斥操作。 2. std::mutex及其衍…...
基于ROS软路由的百元硬件升级方案实现突破千兆宽带
前言 很多用户得利于FTTR光网络不断推广,家用宽带带宽已经实现千兆速率的突破。而现在很多ISP运营商已经在多个城市率先推出2000M光宽带。这种情况下,要想将自家宽带的带宽能够充分发挥利用,就需要对原有的千兆设备进行升级来满足突破千兆的…...
OpenHarmony实战开发-分布式关系型数据库
介绍 本示例使用ohos.data.relationalStore 接口和ohos.distributedDeviceManager 接口展示了在eTS中分布式关系型数据库的使用,在增、删、改、查的基本操作外,还包括分布式数据库的数据同步同能。 效果预览 使用说明: 1.启动应用后点击“”按钮可以添…...
图片标注编辑平台搭建系列教程(6)——fabric渲染原理
原理 fabric的渲染步骤大致如下: 渲染前都设置背景图然后调用ctx.save(),存储画布的绘制状态参数然后调用每个object自身的渲染方法最后调用ctx.restore(),恢复画布的保存状态后处理,例如控制框的渲染等 值得注意的是࿰…...
Qt中QIcon图标设置(标题、菜单栏、工具栏、状态栏图标)
1 exe程序图标概述 在 Windows 操作系统中,程序图标一般会涉及三个地方; (1) 可执行程序(以及对应的快捷方式)的图标 (2) 程序界面标题栏图标 (3)程序在任务…...
C语言程序10题
第101题 (10.0分) 难度:易 第2章 /*------------------------------------------------------- 【程序填空】 --------------------------------------------------------- 功能:计算平均成绩并统计90分以上人数。 --…...
定时器-间歇函数
1.开启定时器 setInterval(function (){console.log(一秒执行一次)},1000) function fn(){console.log(一秒执行一次) } setInterval(fn,1000) //调用有名的函数,只写函数名 1.函数名字不需要加小括号 2.定时器返回是一个id数字 每个定时器的序号是不一样的 2.关…...
Ajax-XMLHttpRequest基本使用
一、Ajax的原理 就是XMLHttpRequest对象。 二、为什么学习XHR? 有更多与服务器数据通信方式,了解Ajax内部。 三、XHR使用步骤 1.创建XHR对象 2.调用open方法,设置url和请求方法 3.监听loadend事件,接受结果 4.调用send方法…...
门控循环单元(GRU)
概述 门控循环单元(Gated Recurrent Unit, GRU)由Junyoung Chung等人于2014年提出,原论文为《Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling》。GRU是循环神经网络(Recurrent Neural Network, …...
789. 数的范围 (二分学习)左端大右,右端小左
题目链接https://www.acwing.com/file_system/file/content/whole/index/content/4317/ 当求左端点时,条件是a【mid】大于等于x,并把右端点缩小。 当求右端点时,条件是a【mid】小于等于x,并把左端点扩大。 1.确定一个区间&…...
docker logs 查找日志常用命令
docker logs 是什么 docker logs 是 Docker 命令行工具提供的一个命令,用于查看容器的日志输出。它可以显示容器在运行过程中生成的标准输出(stdout)和标准错误输出(stderr),帮助用户诊断容器的行为和排查…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
