【Spring】MVC
Spring MVC 是基于Servlet API构建的原始的Web框架,是 Spring 框架的一个重要模块,它实现了模型 - 视图 - 控制器(MVC)设计模式,用于构建灵活、可维护的 Web 应用程序。MVC设计模式模型(Model):负责处理业务逻辑和数据存储。它包含了应用程序的数据和业务规则,可以是 Java 对象、数据库实体等。视图(View):负责呈现用户界面。它可以是 HTML 页
🔥个人主页: 中草药
😀一、简介
Spring MVC 是基于Servlet API构建的原始的Web框架,是 Spring 框架的一个重要模块,它实现了模型 - 视图 - 控制器(MVC)设计模式,用于构建灵活、可维护的 Web 应用程序。
MVC 设计模式将应用程序分为三个主要部分:
- 模型(Model):负责处理业务逻辑和数据存储。它包含了应用程序的数据和业务规则,可以是 Java 对象、数据库实体等。
- 视图(View):负责呈现用户界面。它可以是 HTML 页面、JSP 文件、XML 视图等,用于将模型中的数据展示给用户。
- 控制器(Controller):负责处理用户请求并协调模型和视图之间的交互。它接收用户的输入,调用模型进行业务处理,并选择合适的视图来呈现结果。
Spring MVC 通过将这些部分解耦,使得开发人员可以更加专注于各自的领域,提高了开发效率和代码的可维护性。
什么是Servlet呢?Servlet 是一种实现动态页面的技术. 准确来讲Servlet是一套 Java Web 开发的规范,或者说是一套 Java Web 开发的技术标准。只有规范并不能做任何事情,必须要有人去实现它. 所谓实现 Servlet 规范,就是真正编写代码去实现 Servlet 规范提到的各种功能,包括类、方法、属性等.Servlet 规范是开放的,除了 Sun 公司,其它公司也可以实现 Servlet 规范,目前常见的实现了 Servlet 规范的产品包括 Tomcat、Weblogic、Jetty、Jboss、WebSphere 等,它们都被称 为"Servlet 容器". Servlet 容器用来管理程序员编写的 Servlet 类.
😄二、工作原理
- 客户端发送请求:用户通过浏览器发送 HTTP 请求到服务器。
- DispatcherServlet 接收请求:Spring MVC 的核心组件 DispatcherServlet 接收请求,并根据请求的 URL 找到对应的控制器(Controller)。
- 控制器处理请求:控制器接收请求后,调用相应的业务逻辑处理方法,对请求进行处理。控制器可以访问模型(Model)来获取数据,并将数据传递给视图(View)进行呈现。
- 选择视图:控制器根据处理结果选择合适的视图,并将模型数据传递给视图。
- 视图呈现结果:视图使用模型数据生成响应内容,并将其返回给 DispatcherServlet。
- DispatcherServlet 返回响应:DispatcherServlet 将视图生成的响应内容返回给客户端浏览器。
🤣三、核心组件
MVC 是 Model,View,Controller 的缩写,他是软件工程的一种软件架构设计模式,把软件系统分为模型,视图,控制器三个基本部分:
- Controller:控制器负责处理用户请求,调用业务逻辑处理方法,并选择合适的视图来呈现结果。可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回哪一个视图,即用来连接 Model 和 View
- Model:是应用程序的主体部分,用来处理程序中的数据逻辑部分
- View:应用程序当中专门用来与浏览器进行交互,展示数据的资源
此外还有一些组件如下:
- DispatcherServlet:Spring MVC 的核心 servlet,负责接收用户请求并将其转发给相应的控制器进行处理。它还负责选择合适的视图来呈现响应结果。
- HandlerMapping:用于将请求 URL 映射到相应的控制器。Spring MVC 提供了多种实现方式,如基于注解的映射和基于 XML 配置的映射。
- ModelAndView:用于封装模型数据和视图信息。控制器可以返回一个 ModelAndView 对象,其中包含了要呈现的视图名称和模型数据。
- ViewResolver:用于将视图名称解析为实际的视图对象。Spring MVC 提供了多种视图解析器,如 JSP 视图解析器、FreeMarker 视图解析器等。
🙂四、注解配置
创建 Spring MVC项目
Spring MVC 提供了丰富的注解来简化开发过程。
1.@RestController
@RestController
是一个组合注解,它相当于@Controller
和@ResponseBody
的结合。
-
作用:用于标识一个控制器类,表明该类中的方法将返回数据而不是视图。当一个方法被注解为
@RestController
的类中的方法被调用时,Spring 会将方法的返回值直接序列化为 JSON、XML 或其他适当的格式,并将其作为 HTTP 响应体返回给客户端。 -
示例:
@RestController
public class MyController {
// 方法定义...
}
2.@RequestMapping
@RequestMapping
用于映射请求的 URL 到特定的处理方法上。
-
作用:可以在类级别和方法级别上使用。在类级别上使用时,它定义了一个基本的请求路径前缀,而在方法级别上使用时,它进一步细化了请求的路径和 HTTP 方法等。
-
属性:
value
:指定请求的 URL 路径。method
:指定请求的 HTTP 方法,如GET
、POST
、PUT
、DELETE
等。consumes
:指定请求的内容类型。produces
:指定响应的内容类型。
-
示例:
@RestController
@RequestMapping("/api")
public class MyController {
@RequestMapping(value = "/users", method = RequestMethod.GET)
public List<User> getUsers() {
// 返回用户列表
}
}
3.@RequestParam
@RequestParam
用于获取请求参数。
-
作用:可以从 URL 的查询参数或者表单数据中获取参数值,并将其传递给方法参数。
-
属性:
value
:指定参数的名称。required
:表示该参数是否必填,默认为true
。
-
示例:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/search")
public List<User> searchUsers(@RequestParam("keyword") String keyword) {
// 根据关键字搜索用户
}
}
4.@RequestHeader
- 作用:用于从 HTTP 请求的头部获取特定的值,并将其注入到方法参数中。
- 示例:
@Controller
public class MyController {
@RequestMapping("/header")
public String getHeaderValue(@RequestHeader("Accept-Language") String language) {
// 使用 language
return "resultPage";
}
}
这个例子中,方法参数language
会被注入请求头部中Accept-Language
的值。
5.@RequestPart
- 作用:接收特定部分的请求内容,绑定复杂的对象
- 示例:
@RestController public class FileUploadController { @PostMapping("/upload") public String uploadFile(@RequestPart("file") MultipartFile file, @RequestPart("description") String description) { // 处理文件上传和文本参数 if (!file.isEmpty()) { // 保存文件等操作 System.out.println("File name: " + file.getOriginalFilename()); System.out.println("Description: " + description); return "File uploaded successfully."; } else { return "Failed to upload file."; } } }
这个代码就实现了文件的上传
6.@ResponseBody
- 作用:该注解用于将控制器方法的返回值直接写入 HTTP 响应体中,而不是将其解析为视图名称。通常用于返回 JSON、XML 等数据格式的响应。
- 示例:
@RestController
public class MyController {
@RequestMapping("/data")
@ResponseBody
public MyData getData() {
MyData data = new MyData();
// 设置数据
return data;
}
}
这里的方法返回一个自定义对象MyData
,由于有@ResponseBody
注解,这个对象会被序列化为合适的数据格式(如 JSON)并写入响应体。
7.@PathVariable
@PathVariable
用于获取 URL 中的路径变量。
-
作用:当请求的 URL 中包含动态的部分时,可以使用
@PathVariable
注解将其提取出来作为方法参数。 -
示例:
@RestController
@RequestMapping("/api/users")
public class MyController {
@GetMapping("/{id}")
public User getUserById(@PathVariable("id") Long id) {
// 根据用户 ID 返回用户对象
}
}
在上述例子中,当客户端发送请求/api/users/123
时,id
参数将被赋值为123
。
8.@CookieValue
- 作用:用于从 HTTP 请求中获取特定的 Cookie 值,并将其注入到方法参数中。
- 示例:
@Controller
public class MyController {
@RequestMapping("/test")
public String testMethod(@CookieValue("myCookie") String cookieValue) {
// 使用 cookieValue
return "resultPage";
}
}
在这个例子中,方法参数cookieValue
会被注入请求中名为myCookie
的 Cookie 的值。
9.@SessionAttribute
- 作用:用于将模型中的属性存储到 HTTP 会话中,或者从会话中获取特定的属性并注入到方法参数中。
- 示例:
@Controller
public class MyController {
@RequestMapping("/set")
public String setAttribute(Model model) {
model.addAttribute("sessionData", "someValue");
return "redirect:/get";
}
@RequestMapping("/get")
public String getAttribute(@SessionAttribute("sessionData") String data) {
// 使用 data
return "resultPage";
}
}
在setAttribute
方法中,将一个值存储到会话中,然后在getAttribute
方法中,通过@SessionAttribute
注解从会话中获取这个值并注入到方法参数中。
😉五、Spring MVC的优势
- 松耦合:Spring MVC 实现了模型、视图和控制器的分离,使得各个部分之间的耦合度降低,提高了代码的可维护性和可扩展性。
- 灵活性:Spring MVC 提供了丰富的配置选项和扩展点,可以根据不同的需求进行定制和扩展。
- 易于测试:由于 Spring MVC 的各个部分之间解耦,使得单元测试和集成测试更加容易。
- 强大的视图技术支持:Spring MVC 支持多种视图技术,如 JSP、FreeMarker、Thymeleaf 等,可以根据项目需求选择合适的视图技术。
- 良好的社区支持:Spring MVC 是 Spring 框架的一部分,拥有庞大的社区和丰富的文档资源,遇到问题可以很容易地找到解决方案。
😊六、JSON
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于一个子集的 JavaScript 编程语言,是易于人阅读和编写同时也易于机器解析和生成的数据格式。JSON 格式广泛用于 Web 应用程序之间传输数据,并且得到了几乎所有编程环境的支持。
1.基本语法
- JSON 数据以键值对的形式表示。
- 键必须是字符串,而值可以是合法的 JSON 数据类型(字符串、数字、对象、数组、布尔值或 null)。
- JSON 对象使用花括号 {} 来定义。
- JSON 数组使用方括号 [] 来定义。
- 成员之间用逗号分隔。
- 字符串必须使用双引号包围。
2.特点
- 简洁性:JSON 的语法非常简洁,易于阅读和编写。与 XML 相比,JSON 没有过多的标签和属性,减少了数据的冗余。
- 可读性:JSON 的文本格式可以很容易地理解和编辑数据。这对于调试和手动修改数据非常有帮助。
- 跨平台性:JSON 可以在不同的操作系统和编程语言中使用,因为它是一种基于文本的格式。大多数编程语言都提供了对 JSON 的支持,可以轻松地解析和生成 JSON 数据。
- 可扩展性:JSON 可以很容易地扩展,因为它可以包含任意复杂的对象和数组结构。可以根据需要添加新的键值对或数组元素,而不会影响现有的数据结构。
3.JSON 与 XML 的比较
- JSON 比 XML 更小、更快,更易解析。
- JSON 直接映射到数据结构,如数组和对象。
- XML 更适合于文档标记,提供了更多的元数据选项。
- JSON 不支持注释,XML 支持。
4.JSON 在实际中的应用
- API 数据交互:Web API 常返回 JSON 格式的数据。
- 存储配置信息:应用程序可以将配置保存为 JSON 文件。
- 客户端存储:例如,通过浏览器的 localStorage 或 sessionStorage 存储 JSON 数据。
5.使用
在postman中
在fiddle之中
6.参考资源
😉七.应用分层
在软件开发中,目前更主流的开发方式是“前后端分离”方式,后端开发工程师不在关注前端的的实现,应用分层是一种重要的设计模式,它将应用程序按照不同的功能和职责划分为多个层次,每个层次专注于特定的任务,从而提高软件的可维护性、可扩展性和可测试性。
1、常见的分层结构(三层架构)
-
)表现层(Presentation Layer)
- 作用:这一层主要负责与用户进行交互,接收用户的输入并将应用程序的结果呈现给用户。
- 包含内容:通常包括用户界面(如网页、移动应用界面等)、用户输入验证逻辑等。在 Web 应用中,表现层可能由 HTML、CSS、JavaScript 等技术实现;在桌面应用中,可能使用 Java Swing、Python Tkinter 等图形界面库。
- 举例:在一个电子商务网站中,表现层负责展示商品列表、接收用户的购物车操作等。
-
)业务逻辑层(Business Logic Layer)
- 作用:这一层包含了应用程序的核心业务逻辑,处理具体的业务规则和流程。
- 包含内容:包括业务对象、业务规则、业务流程的实现等。业务逻辑层通常与数据访问层和表现层进行交互,它接收表现层传来的用户请求,调用数据访问层获取或更新数据,并将处理结果返回给表现层。
- 举例:在一个银行系统中,业务逻辑层负责处理账户余额查询、转账等业务操作,确保这些操作符合银行的业务规则。
-
)数据访问层(Data Access Layer)
- 作用:该层主要负责与数据库或其他数据存储系统进行交互,实现数据的存储、检索、更新和删除等操作。
- 包含内容:通常包括数据库连接、SQL 语句执行、数据映射等功能。数据访问层将数据库操作封装在特定的方法中,为业务逻辑层提供统一的数据访问接口,使得业务逻辑层不需要关心具体的数据存储细节。
- 举例:在一个学生管理系统中,数据访问层负责从数据库中读取学生信息、插入新的学生记录、更新学生成绩等操作。
表现层:就是展现数据结果,接受用户指令的,是最接近用户的一层
业务逻辑层:负责处理业务逻辑,里面有复杂的业务逻辑实现
数据层:负责存储和管理与应用程序相关的数据
2、应用分层的好处
-
提高可维护性
- 每个层次的职责明确,代码的修改和维护更加容易。例如,如果需要修改数据库结构,只需要在数据访问层进行相应的调整,而不会影响到业务逻辑层和表现层的代码。
- 不同层次的代码可以由不同的开发人员负责,提高开发效率。
-
增强可扩展性
- 可以方便地添加新的功能或修改现有功能。例如,如果要添加一个新的业务流程,只需要在业务逻辑层进行扩展,而不需要修改其他层次的代码。
- 可以根据需要更换不同的技术实现。例如,如果要将数据库从 MySQL 切换为 Oracle,只需要修改数据访问层的代码,而不会影响到其他层次。
-
改善可测试性
- 每个层次可以独立进行测试,提高测试的效率和准确性。例如,可以对业务逻辑层进行单元测试,而不需要依赖于数据库或用户界面。
- 可以使用模拟对象(mock object)来模拟其他层次的行为,方便进行测试。
总之,应用分层是一种有效的软件设计模式,它可以帮助开发人员构建出更加清晰、可维护、可扩展和可测试的应用程序。
3、MVC 和三层架构的区别和联系
从概念来看,这两者都是软件工程领域的架构模式
MVC架构模式:模型,视图,控制器
三层架构:表现层,业务逻辑层,数据层
如下图的对应关系
有人说,三层架构是MVC模式的一种实现,也有人说,MVC是三层架构的一种替代方案 ,这其实是不同角度看待问题所呈现的不同观点
二者其实是不同角度对"软件工程"进行了抽象
MVC模式 强调了数据和视图分离,将数据展示和数据处理进行了分开,又通过控制器对二者进行了组合
三层架构 强调了不同维度数据处理的高内聚和低耦合,将交互界面,业务处理,数据库操作的逻辑分开,角度不同,谈不上互相替代
二者的目的是相同的,都是“解耦,分层,代码复用”
4、高聚合,低耦合
“高聚合、低耦合” 是一种重要的软件设计原则。
一、高聚合(High Cohesion)
-
定义
- 高聚合指的是一个软件模块内部的各个元素之间具有高度的关联性和功能性内聚。也就是说,一个高聚合的模块应该专注于完成一个单一的、明确的任务或功能。
-
好处
- 易于理解和维护:由于模块的功能单一明确,开发人员可以更容易地理解模块的作用和行为,从而更容易进行维护和修改。
- 可重用性高:高聚合的模块通常具有较高的独立性,因此可以更容易地在不同的项目或系统中被重用。
- 提高软件质量:高聚合的模块通常具有更高的可靠性和稳定性,因为它们的功能相对简单,不容易出现复杂的错误。
-
实现方法
- 功能单一原则:确保一个模块只完成一个特定的功能,避免将多个不相关的功能放在一个模块中。
- 职责明确:明确模块的职责和边界,使得模块内部的各个元素都为实现该模块的特定功能而服务。
二、低耦合(Low Coupling)
-
定义
- 低耦合指的是不同软件模块之间的依赖关系尽可能地少和弱。也就是说,一个低耦合的系统中,各个模块之间的交互应该尽可能地简单和松散。
-
好处
- 易于扩展和修改:当需要对系统进行扩展或修改时,低耦合的设计可以使得对一个模块的修改不会影响到其他模块,从而降低了修改的难度和风险。
- 提高软件的可维护性:低耦合的系统中,各个模块之间的独立性较高,因此可以更容易地进行维护和调试。
- 便于团队协作:低耦合的设计可以使得不同的开发人员可以独立地开发和维护不同的模块,从而提高了团队协作的效率。
-
实现方法
- 接口设计:通过定义清晰的接口来实现模块之间的交互,使得模块之间的依赖关系仅限于接口的定义。
- 依赖注入:使用依赖注入技术可以将模块之间的依赖关系从代码中分离出来,使得模块的依赖关系更加清晰和易于管理。
- 消息传递:使用消息传递机制可以使得模块之间的交互更加松散和灵活,降低模块之间的耦合度。
高内聚:一个模块中各个元素之间的联系的紧密程度,联系程度越高,内聚性越强
低耦合:软件中,各个层,模块之间的依赖关联程度越低越好。修改一出代码,其他模块的代码改动的越少越好
总之,“高聚合、低耦合” 的设计原则可以帮助开发人员构建出更加易于维护、扩展和重用的软件系统。
能用众力,则无敌于天下矣;能用众智,则无畏于圣人矣。——孙权
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐
制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸
更多推荐
所有评论(0)