Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中。它的正式名称“Spring Web MVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC".
Servlet 是⼀种实现动态⻚⾯的技术. 准确来讲Servlet是⼀套 Java Web 开发的规范,或者说是⼀套
Java Web 开发的技术标准. 只有规范并不能做任何事情,必须要有⼈去实现它. 所谓实现 Servlet 规范,就是真正编写代码去实现 Servlet 规范提到的各种功能,包括类、⽅法、属性等.
Servlet 规范是开放的,除了 Sun 公司,其它公司也可以实现 Servlet 规范,⽬前常⻅的实现了Servlet 规范的产品包括 Tomcat、Weblogic、Jetty、Jboss、WebSphere 等,它们都被称 为"Servlet 容器". Servlet 容器⽤来管理程序员编写的 Servlet 类.
Web服务器
浏览器和服务器两端进⾏数据交互, 使⽤的就是HTTP协议
HTTP 协议就是 HTTP 客户端和 HTTP 服务器之间的交互数据的格式.
Web 服务器就是对HTTP协议进⾏封装, 程序员不需要直接对协议进⾏操作(⾃⼰写代码去解析http协议规则),让Web开发更加便捷, 所以Web服务器也被称为WWW服务器, HTTP服务器, 主要功能是提供⽹上信息浏览服务.
常⻅的Web服务器有: Apache,Nginx, IIS, Tomcat, Jboss等
在springboot里默认集成了tomcat服务器,tomcat的默认端口就是8080,所以访问我们所运行的程序端口就是8080;
我们访问本机服务器的默认网址就是 http://127.0.0.1:8080
浏览器输⼊URL之后, 发起请求, 就和服务器之间建⽴了连接


访问常见错误
404 表⽰⽤户访问的资源不存在.,⼤概率是 URL 的路径写的不正确.
要么是访问的路径写错了,要么是程序的路径配置错了。
500 服务器出现内部错误. ⼀般是服务器的代码执⾏过程中遇到了⼀些特殊情况(服务器异常崩溃)会产⽣这个状态码.
2XX 表示成功
3XX 表示重定向
4XX 客户端错误(请求有问题,比如参数错了,路径错了,格式错了)
5XX 服务端错误
Spring-Web-Mvc
Mvc定义

View(视图) 指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.
Model(模型) 是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.
Controller(控制器)可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型 来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型
什么是spring web mvc
MVC 是⼀种架构设计模式, 也是⼀种思想, ⽽ Spring MVC 是对 MVC 思想的具体实现. 除此之外,
Spring MVC还是⼀个Web框架.
总结来说,Spring MVC 是⼀个实现了 MVC 模式的 Web 框架.
所以, Spring MVC主要关注有两个点:
MVC
Web框架
Spring MVC 全称是 Spring Web MVC
Spring Boot 只是实现Spring MVC的其中⼀种⽅式⽽已.
Spring Boot 可以添加很多依赖, 借助这些依赖实现不同的功能. Spring Boot 通过添加Spring Web MVC框架, 来实现web功能.
⽐如: 厨房可以⽤来做饭, 但真实实现做饭功能的是⽕以及各种做饭相关的⻝材和⼯具.
厨房就好⽐是SpringBoot, 厨房可以装柜⼦, 实现收纳功能, 装燃⽓灶等, 实现做饭功能.
做饭这个事, 就是MVC, 在⼏千年前, 有⽕有⻝材就可以实现做饭

使用MVC
建立连接
获取请求
返回响应
项目准备
建立连接

@RequestMapping
@RequestMapping 是 Spring Web MVC 应⽤程序中最常被⽤到的注解之⼀,它是⽤来注册接⼝的
路由映射的.
表⽰服务收到请求时, 路径为 /sayHi 的请求就会调⽤ sayHi 这个⽅法的代码.
路由映射: 当⽤⼾访问⼀个 URL 时, 将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射.
这个注解同时是类注解和方法注解,在同时在一个类上给类和方法进行注解,那么这个路由映射访问的地址就是类路径+方法路径
@RequestMapping 同时支持get和post。
如何指定支持get或者post。
我们可以显⽰的指定@RequestMapping 来接收POST的情况,如下所示:
如果要指定接收的话,那么就要在注解前面添加属性名。
因为该注解只有一个参数默认就是给value的,如果有多个参数就要指明属性。
实际上网络传递过来的都是String类型,他会在匹配类型的时候进行转换,匹配的上就转换赋值,匹配不上就不赋值。
要想只支持get的话,把method 里的 post 改成 get。
@GetMapping 和 @PostMapping 和上面的等价。
路径在请求方法不同时,可以一样,其他都不行。
@RestController
在接收web请求的时候,项目有很多类,不可能每个类都扫描一遍,这个注解的其中一个功能就是能够起到一个标识的作用,会在接收请求的时候扫描这个类有没有对应的路由映射。不加的话可能会报错。
传参
传递单个参数
接收单个参数, 在 Spring MVC 中直接⽤⽅法中的参数就可以

使⽤浏览器发送请求并传参
http://127.0.0.1:8080/param/m1?name=spring

可以看到, 后端程序正确拿到了name参数的值.
Spring MVC 会根据⽅法的参数名, 找到对应的参数, 赋值给⽅法

在传递参数的时候,参数名一定要一样的,如果不一样是接收不到参数的。

使⽤基本类型来接收参数时, 参数必须传(除boolean类型), 不传参数会报500错误
对于包装类型, 如果不传对应参数,Spring 接收到的数据则为null
所以企业开发中,对于参数可能为空的数据,建议使⽤包装类型
基本类型数据类型不匹配时, 会报400错误.
传递多个参数
使⽤浏览器发送请求并传参: http://127.0.0.1:8080/param/m2?name=zhangsan&password=123456


当有多个参数时,前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果
⽐如访问: http://127.0.0.1:8080/param/m2?password=123456&name=zhangsan 同样可以拿到正
确的结果

传递对象
如果参数⽐较多时, ⽅法声明就需要有很多形参. 并且后续每次新增⼀个参数, 也需要修改⽅法声明.
可以把这些参数封装为⼀个对象.
Spring MVC 也可以⾃动实现对象参数的赋值,⽐如 Person 对象:


使⽤浏览器发送请求并传参: http://127.0.0.1:8080/param/m3?
id=5&name=zhangsan&password=123456

可以看到, 后端程序正确拿到了Person对象⾥各个属性的值

Spring 会根据参数名称⾃动绑定到对象的各个属性上, 如果某个属性未传递, 则赋值为null(基本类型则赋值为默认初识值, ⽐如int类型的属性, 会被赋值为0)
后端参数重命名(后端参数映射)
某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个time 给后端,⽽后端是使⽤ createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值.
具体⽰例如下,后端实现代码:

使⽤浏览器发送请求并传参: http://127.0.0.1:8080/param/m4?time=2023-09-12

可以看到, Spring可以正确的把浏览器传递的参数time绑定到了后端参数caretetime参数上
此时, 如果浏览器使⽤createtime进⾏参数传递呢?
访问URL: http://127.0.0.1:8080/param/m4?createtime=2023-09-12
浏览器响应结果:


控制台打印⽇志显⽰: 请求参数 'time' 不存在
可以得出结论:
使⽤ @RequestParam 进⾏参数重命名时, 请求参数只能和 @RequestParam 声明的名称⼀ 致, 才能进⾏参数绑定和赋值.
使⽤ @RequestParam 进⾏参数重命名时, 参数就变成了必传参数.
@RequestParam 本质上是对参数进行绑定。
可以通过required设置false改为非必传参数。
传递数组
当多个参数命名一样时,会自动组合成数组传递过去。
或者将一个参数内的数据通过逗号分隔,也会视为一个数组

使⽤浏览器发送请求并传参:
数组参数:请求参数名与形参数组名称相同且请求参数为多个, 后端定义数组类型形参即可接收参数
http://127.0.0.1:8080/param/m5?
arrayParam=zhangsan&arrayParam=lisi&arrayParam=wangwu
或者使⽤ http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu
或者使⽤ http://127.0.0.1:8080/param/m5?arrayParam=zhangsan,lisi,wangwu

传递集合
集合参数:和数组类似, 同⼀个请求参数名有为多个, 且需要使⽤ @RequestParam 绑定参数关系
因为在默认的情况下,请求中参数名相同的多个值,是封装到数组里的. 如果要封装到集合,要使⽤@RequestParam 绑定参数关系,绑定好后就传递给了集合。
请求⽅式和数组类似:浏览器传参:
⽅式⼀: http://127.0.0.1:8080/param/m6?listParam=zhangsan&listParam=lisi&listParam=wangwu
⽅式⼆: http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu
%2c 是逗号的转义编码, 解码后的url为: http://127.0.0.1:8080/param/m6?
listParam=zhangsan,lisi,wangwu


Json
JSON概念
JSON:JavaScript Object Notation 【JavaScript 对象表⽰法】
JSON是⼀种轻量级的数据交互格式. 它基于 ECMAScript (欧洲计算机协会制定的js规范)的⼀个⼦集,
采⽤完全独⽴于编程语⾔的⽂本格式来存储和表⽰数据。--百度百科
简单来说:JSON就是⼀种数据格式, 有⾃⼰的格式和语法, 使⽤⽂本表⽰⼀个对象或数组的信息, 因此
JSON本质是字符串. 主要负责在不同的语⾔中数据传递和交换.
类似于:
国际通⽤语⾔-英语
中国56个⺠族不同地区的通⽤语⾔-普通话
在国际上使用英语来沟通,但各民族也有自己的语言
JSON语法
JSON 是⼀个字符串,其格式⾮常类似于 JavaScript 对象字⾯量的格式
我们先来看⼀段JSON数据


和上⾯描述的数据⼀样, 只不过上⾯的进⾏了格式化, 更易读.
JSON的语法:
数据在 键值对(Key/Value) 中
数据由逗号 , 分隔
对象⽤ {} 表⽰
数组⽤ [] 表⽰
值可以为对象, 也可以为数组, 数组中可以包含多个对象
JSON的两种结构
对象: ⼤括号 {} 保存的对象是⼀个⽆序的 键值对 集合. ⼀个对象以左括号 { 开始, 右括号 }
结束。每个"键"后跟⼀个冒号 : ,键值对使⽤逗号 , 分隔
数组: 中括号 [] 保存的数组是值(value)的有序集合. ⼀个数组以左中括号 [ 开始, 右中括
号 ] 结束,值之间使⽤逗号 , 分隔。
Json字符串和Java对象互转
JSON本质上是⼀个字符串, 通过⽂本来存储和描述数据
Spring MVC框架也集成了JSON的转换⼯具jackson,这只是转换工具的一种,想去用其他的可以自己导入依赖,我们可以直接使⽤, 来完成JSON字符串和Java对象的互转。

使⽤ObjectMapper 对象提供的两个⽅法, 可以完成对象和JSON字符串的互转
writeValueAsString: 把对象转为JSON字符串
readValue: 把字符串转为对象
JSON优点
简单易⽤: 语法简单,易于理解和编写,可以快速地进⾏数据交换
跨平台⽀持: JSON可以被多种编程语⾔解析和⽣成, 可以在不同的平台和语⾔之间进⾏数据交换和传输
轻量级: 相较于XML格式, JSON数据格式更加轻量级, 传输数据时占⽤带宽较⼩, 可以提⾼数据传输速度
易于扩展: JSON的数据结构灵活,⽀持嵌套对象和数组等复杂的数据结构,便于扩展和使⽤
安全性: JSON数据格式是⼀种纯⽂本格式,不包含可执⾏代码, 不会执⾏恶意代码,因此具有较⾼的安全性。
传递JSON对象
接收JSON对象, 需要使⽤ @RequestBody
注解RequestBody: 请求正⽂,意思是这个注解作⽤在请求正⽂的数据绑定,请求参数必须在写在请求正⽂中
后端代码

成员名要对应,属性顺序不做要求,list和数组对顺序有要求。
可以看到显示的是字符串类型,这是因为spring自动将json转换成了对象,所以不需要手动转换。
如果创建了有参的构造函数,最好再创建一个无参的默认构造函数。
获取URL中参数@PathVariable
path variable: 路径变量
和字⾯表达的意思⼀样, 这个注解主要作⽤在请求URL路径上的数据绑定
默认传递参数写在URL上,SpringMVC就可以获取到url上的参数
后端实现代码:

{}大括号包括的就是@PathVariable的变量,只要匹配的上就可以获取到,匹配不上的话网页就会报错。

如果⽅法参数名称和需要绑定的URL中的变量名称⼀致时, 可以简写, 不⽤给@PathVariable的属性赋值, 如上述例⼦中的id变量
如果⽅法参数名称和需要绑定的URL中的变量名称不⼀致时, 需要@PathVariable的属性value赋值,
如上述例⼦中的userName变量
上传⽂件@RequestPart


Cookie和Session
HTTP 协议⾃⾝是属于 "⽆状态" 协议.
"⽆状态" 的含义指的是:
默认情况下 HTTP 协议的客⼾端和服务器之间的这次通信, 和下次通信之间没有直接的联系.
但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆⽹站成功后, 第⼆次访问的时候服务器就能知道该请求是否是已经登陆过了.
⽐如去医院挂号
看病之前先挂号. 挂号时候需要提供⾝份证号, 同时得到了⼀张 "就诊卡", 这个就诊卡就相当于患者的 "令牌".
后续去各个科室进⾏检查, 诊断, 开药等操作, 都不必再出⽰⾝份证了, 只要凭就诊卡即可识别出当前患者的⾝份.
看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的⾝份和就诊卡的关联就销毁了. (类似于⽹站的注销操作)
⼜来看病, 可以办⼀张新的就诊卡, 此时就得到了⼀个新的 "令牌"
理解Session
我们先来了解⼀下什么是会话.
会话: 对话的意思
在计算机领域, 会话是⼀个客⼾与服务器之间的不中断的请求响应. 对客⼾的每个请求,服务器能够识别出请求来⾃于同⼀个客⼾. 当⼀个未知的客⼾向Web应⽤程序发送第⼀个请求时就开始了⼀个会话.
当客⼾明确结束会话或服务器在⼀个时限内没有接受到客⼾的任何请求时,会话就结束了.
⽐如我们打客服电话
每次打客服电话, 是⼀个会话. 挂断电话, 会话就结束了
下次再打客服电话, ⼜是⼀个新的会话.
如果我们⻓时间不说话, 没有新的请求, 会话也会结束.
服务器同⼀时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是属于哪个⽤⼾, 也就是属于哪个会话, 就需要在服务器这边记录每个会话以及与⽤⼾的信息的对应关系.
Session是服务器为了保存⽤⼾信息⽽创建的⼀个特殊的对象.
Session的本质就是⼀个 "哈希表", 存储了⼀些键值对结构. Key 就是SessionID, Value 就是⽤⼾信息(⽤⼾信息可以根据需求灵活设计)

essionId 是由服务器⽣成的⼀个 "唯⼀性字符串", 从 Session 机制的⻆度来看, 这个唯⼀性字符串称为 "SessionId". 但是站在整个登录流程中看待, 也可以把这个唯⼀性字符串称为 "token".
上述例⼦中的令牌ID, 就可以看做是SessionId, 只不过令牌除了ID之外, 还会带⼀些其他信息, ⽐如时间, 签名等.
当⽤⼾登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId返回给客⼾端. (通过
HTTP 响应中的 Set-Cookie 字段返回).
客⼾端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId. (通过 HTTP 请求中的
Cookie 字段带上).
服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的⽤⼾信息, 再进⾏后
续操作.找不到则重新创建Session, 并把SessionID返
ession 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.
Cookie 和 Session 的区别
Cookie 是客⼾端保存⽤⼾信息的⼀种机制. Session 是服务器端保存⽤⼾信息的⼀种机制.
Cookie 和 Session之间主要是通过 SessionId 关联起来的, SessionId 是 Cookie 和 Session 之间的桥梁
Cookie 和 Session 经常会在⼀起配合使⽤. 但是不是必须配合.
完全可以⽤ Cookie 来保存⼀些数据在客⼾端. 这些数据不⼀定是⽤⼾⾝份信息, 也不⼀定是
SessionId
Session 中的sessionId 也不需要⾮得通过 Cookie/Set-Cookie 传递, ⽐如通过URL传递.
获取cookie
Spring MVC是基于 Servlet API 构建的原始 Web 框架, 也是在Servlet的基础上实现的
HttpServletRequest , HttpServletResponse 是Servlet提供的两个类, 是Spring
MVC⽅法的内置对象. 需要时直接在⽅法中添加声明即可.
HttpServletRequest
这个类代表客⼾端的请求, 当客⼾端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的⽅法,可以获得客⼾端请求的所有信息.
HttpServletResponse
这个类代表服务器的响应. HTTP响应的信息都在这个对象中, ⽐如向客⼾端发送的数据, 响应头, 状态码等. 通过这个对象提供的⽅法, 可以获得服务器响应的所有内容
Spring MVC在这两个对象的基础上进⾏了封装, 给我们提供更加简单的使⽤⽅法。
这两个参数要使用的话直接定义在请求里就可以,不规定顺序,名称也可以随便定义。
简洁获取Cookie
也有更简洁的⽅式获取Cookie
获取session


HttpSession getSession(boolean create);
HttpSession getSession();
Session读取



获取Header



响应
对于请求的默认扫描路径是启动类的目录以及其子孙目录,而为了避免大量的无用扫描就需要加上注解来表明这是一个controller类。
需要用到@restcontroller和@controller和其他特定的注解
这两个注解的区别
@restcontroller是@controller和@responsebody的组合
@controller注解代表返回的是视图的路径;
之前说过现在前后端分离不再返回视图,所以@controller注解基本上用不到了,但是如果用controller注解给类注解上了,想要返回数据可以在方法上加上@responsebody注解就可以了。
返回json
对象或者数组,list,map这些类型等,默认返回的就是json格式,尽管返回的都是字符串,但是会修改content-type来表明数据的格式,因为content-type没有对象的类型,所以使用json来传递。
设置状态码
Spring MVC会根据我们⽅法的返回结果⾃动设置响应状态码, 程序员也可以⼿动指定状态码
通过Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置

状态码不会影响页面的显示,如果要影响页面的显示,需要另外修改页面,这个错误页面的样式也是可以自定义的
设置heander
Http响应报头也会向客⼾端传递⼀些附加信息, ⽐如服务程序的名称,请求的资源已移动到新地址等, 如:
Content-Type, Local等.
这些信息通过 @RequestMapping 注解的属性来实现
value: 指定映射的URL
method: 指定请求的method类型, 如GET, POST等
consumes: 指定处理请求(request)的提交内容类型(Content-Type),例如application/json,
text/html;
produces: 指定返回的内容类型,还可以同时设置返回值的字符编码
Params: 指定request中必须包含某些参数值时,才让该⽅法处理
headers: 指定request中必须包含某些指定的header值,才能让该⽅法处理请求
查看fiddler
如果不设置produces , ⽅法返回结果为String时, Spring MVC默认返回类型, 是text/html
设置其他Header
设置其他Header的话, 需要使⽤Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置
通过Fiddler来观察设置的结果:

应用分层
为了保证代码的美观和整洁,就用了应用分层。
类似公司的组织架构
公司初创阶段, ⼀个⼈⾝兼数职, 既做财务, ⼜做⼈事, 还有⾏政.
随着公司的逐渐壮⼤, 会把岗位进⾏细分, 划分为财务部⻔, ⼈事部⻔, ⾏政部⻔等. 各个部⻔内部还会
再进⾏细分.
项⽬开发也是类似, 最开始功能简单时, 我们前后端放在⼀起开发, 随着项⽬功能的复杂, 我们分为前
端和后端不同的团队, 甚⾄更细粒度的团队. 后端开发也会根据功能再进⾏细分. MVC就是其中的⼀种
拆分⽅式.
但是随着后端⼈员不再涉及前端, 后端开发⼜有了新的分层⽅式.
阿里开发⼿册中, 关于⼯程结构部分, 定义了常⻅⼯程的应⽤分层结构:
应⽤分层 是⼀种软件开发设计思想, 它将应⽤程序分成N个层次, 这N个层次分别负责各⾃的职责, 多个层次之间协同提供完整的功能. 根据项⽬的复杂度, 把项⽬分成三层, 四层或者更多层.
常⻅的MVC设计模式, 就是应⽤分层的⼀种具体体现.
什么需要应⽤分层?
在最开始的时候,为了让项⽬快速上线,我们通常是不考虑分层的. 但是随着业务越来越复杂,⼤量的代码混在⼀起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动⼀处就牵⼀发⽽动全⾝等问题. 所以学习对项⽬进⾏分层就是我们程序员的必修课了.
如何分层(三层架构)
"MVC", 就是把整体的系统分成了 Model(模型), View(视图)和Controller
(控制器)三个层次,也就是将⽤⼾视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是⼀种标准的软件分层架构。

目前现在更主流的开发⽅式是 "前后端分离" 的⽅式, 后端开发⼯程师不再需要关注前端的实现, 所以对于Java后端开发者, ⼜有了⼀种新的分层架构: 把整体架构分为表现层、业务逻辑层和数据层. 这种分层⽅式也称之为"三层架构".
表现层: 就是展⽰数据结果和接受⽤⼾指令的,是最靠近⽤⼾的⼀层;
业务逻辑层: 负责处理业务逻辑, ⾥⾯有复杂业务的具体实现;
数据层: 负责存储和管理与应⽤程序相关的数据

按照上⾯的层次划分, Spring MVC 站在后端开发⼈员的⻆度上, 也进⾏了⽀持, 把上⾯的代码划分为三个部分:
请求处理、响应数据:负责,接收⻚⾯的请求,给⻚⾯响应数据.
逻辑处理:负责业务逻辑处理的代码.
数据访问:负责业务数据的维护操作,包括增、删、改、查等操作
三个部分, 在Spring的实现中, 均有体现:

Controller:控制层。接收前端发送的请求,对请求进⾏处理,并响应数据。
Service:业务逻辑层。处理具体的业务逻辑。
Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查.
MVC 和三层架构的区别和联系
关于⼆者的关系, ⼀直存在不同的观点. 有⼈认为三层架构是MVC模式的⼀种实现, 也有⼈认为MVC是三层架构的替代⽅案, 等等各种说法都有. 根本原因是⼤家站在不同的⻆度来看待这个问题的
从概念上来讲, ⼆者都是软件⼯程领域中的架构模式.
MVC架构模式由三部分组成, 分别是: 模型(Model), 视图(View)和控制器(Controller).
三层架构将业务应⽤划分为:表现层, 业务逻辑层, 数据访问层
![]()
MVC中, 视图和控制器合起来对应三层架构中的表现层. 模型对应三层架构中的业务逻辑层, 数据层,
以及实体类⼆者其实是从不同⻆度对软件⼯程进⾏了抽象.
MVC模式强调数据和视图分离, 将数据展⽰和数据处理分开, 通过控制器对两者进⾏组合.
三层架构强调不同维度数据处理的⾼内聚和低耦合, 将交互界⾯, 业务处理和数据库操作的逻辑分开.
⻆度不同也就谈不上互相替代了,在⽇常的开发中可以经常看到两种共存的情况,⽐如我们设计模型层的时候往往也会拆分出业务逻辑层(Service层)和数据访问层(Dao层)。
但是⼆者的⽬的是相同的, 都是"解耦,分层,代码复⽤"
软件设计原则:⾼内聚低耦合
⾼内聚指的是:⼀个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越⾼,则内聚性越⾼,即 "⾼内聚"。
低耦合指的是:软件中各个层、模块之间的依赖关联程序越低越好。修改⼀处代码, 其他模块的代码改动越少越好
![]()
⾼内聚低耦合⽭盾吗?
不⽭盾, ⾼内聚指的是⼀个模块中各个元素之间的联系的紧密程度, 低耦合指的是各个模块之间的紧 密程度
这就好⽐⼀个企业, 包含很多部⻔, 各个部⻔之间的关联关系要尽可能的⼩, ⼀个部⻔发⽣问题, 要尽可能对降低对其他部⻔的影响, 就是耦合. 但是部⻔内部员⼯关系要尽量紧密, 遇到问题⼀起解决,克服. 这叫做内聚.
⽐如邻⾥邻居, 楼上漏⽔, 楼下遭殃, 就是耦合. 家庭⼀个成员⽣病, 其他成员帮忙照顾, 就叫内聚.
⼀个家庭内部的关系越紧密越好, ⼀个家庭尽可能少的影响另⼀个家庭, 就是低耦合.
应⽤分层的好处
降低层与层之间的依赖, 结构更加的明确, 利于各层逻辑的复⽤
开发⼈员可以只关注整个结构中的其中某⼀层, 极⼤地降低了维护成本和维护时间
可以很容易的⽤新的实现来替换原有层次的实现
有利于标准化
企业规范
类名使⽤⼤驼峰⻛格,但以下情形例外:DO/BO/DTO/VO/AO
⽅法名、参数名、成员变量、局部变量统⼀使⽤⼩驼峰⻛格
包名统⼀使⽤⼩写,点分隔符之间有且仅有⼀个⾃然语义的英语单词.
常⻅命名命名⻛格介绍
⼤驼峰: 所有单词⾸字⺟都需要⼤写, ⼜叫帕斯卡命名法, ⽐如: UserController⼩驼峰: 除了第⼀个单词,其他单词⾸字⺟⼤写,⽐如: userController
蛇形: ⽤下划线(_)作⽤单词间的分隔符, ⼀般⼩写, ⼜叫下划线命名法, ⽐如: user_controller
串形: ⽤短横线(-)作⽤单词间的分隔符, ⼜叫脊柱命名法, ⽐如: user-controller
总结
学习Spring MVC, 其实就是学习各种Web开发需要⽤的到注解
@RequestMapping: 路由映射
@RequestParam: 后端参数重命名
@RequestBody: 接收JSON类型的参数
@PathVariable: 接收路径参数
@RequestPart: 上传⽂件
@ResponseBody: 返回数据
@CookieValue: 从Cookie中获取值
@SessionAttribute: 从Session中获取值
@RequestHeader: 从Header中获取值
@Controller: 定义⼀个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理. 默认返回
视图.
@RestController: @ResponseBody + @Controller 返回数据
Cookie 和Session都是会话机制, Cookie是客⼾端机制, Session是服务端机制. ⼆者通过SessionId
来关联. Spring MVC内置HttpServletRequest, HttpServletResponse两个对象. 需要使⽤时, 直接在
⽅法中添加对应参数即可, Cookie和Session可以从HttpServletRequest中来获取, 也可以直接使⽤
HttpServletResponse设置Http响应状态码.