MVC框架
文章目录
- JSP 和 Servlet
- MVC 的演进
- 1. JSP Model 1
- 2. JSP Model 2
- 3. MVC 的一般化
- 4. MVC 的变体
- 总结
JSP 和 Servlet
- 如果你有使用 Java 作为主要语言开发网站的经历,那么你一定听过别人谈论 JSP 和 Servlet。其中,Servlet 指的是服务端的一种 Java 写的组件,它可以接收和处理来自浏览器的请求,并生成结果数据,通常它会是 HTML、JSON 等常见格式,写入 HTTP 响应,返回给用户。
- 至于 JSP,它的全称叫做 Java Server Pages,它允许静态的 HTML 页面插入一些类似于“<% %>”这样的标记(scriptlet),而在这样的标记中,还能以表达式或代码片段的方式,嵌入一些 Java 代码,在 Web 容器响应 HTTP 请求时,这些标记里的 Java 代码会得到执行,这些标记也会被替换成代码实际执行的结果,嵌入页面中一并返回。这样一来,原本静态的页面,就能动态执行代码,并将执行结果写入页面了。
- 第一次运行时,系统会执行编译过程,并且这个过程只会执行一次:JSP 会处理而生成 Servlet 的 Java 代码,接着代码会被编译成字节码(class 文件),在 Java 虚拟机上运行。之后每次就只需要执行运行过程了,Servlet 能够接受 HTTP 请求,并返回 HTML 文本,最终以 HTTP 响应的方式返回浏览器。
这个过程大致可以这样描述:
编译过程:JSP 页面 → Java 文件(Servlet)→ class 文件(Servlet)
运行过程:HTTP 请求 + class 文件(Servlet)→ HTML 文本
MVC 的演进
- MVC 这种经典的架构模式,它早在 20 世纪 70 年代就被发明出来了,直到现在,互联网上的大多数网站,都是遵从 MVC 实现的,这足以见其旺盛的生命力。MVC 模式包含这样三层:
- 控制器(Controller),恰如其名,主要负责请求的处理、校验和转发。
- 视图(View),将内容数据以界面的方式呈现给用户,也捕获和响应用户的操作。
- 模型(Model),数据和业务逻辑真正的集散地。
- 你可能会想,这不够全面啊,这三层之间的交互和数据流动在哪里?别急,MVC 在历史上经历了多次演进,这三层,再加上用户,它们之间的交互模型,是逐渐变化的。哪怕在今天,不同的 MVC 框架的实现在这一点上也是有区别的。
1. JSP Model 1
- JSP Model 1 是整个演化过程中最古老的一种,请求处理的整个过程,包括参数验证、数据访问、业务处理,到页面渲染(或者响应构造),全部都放在 JSP 页面里面完成。JSP 页面既当爹又当妈,静态页面和嵌入动态表达式的特性,使得它可以很好地容纳声明式代码;而 JSP 的 scriptlet,又完全支持多行 Java 代码的写入,因此它又可以很好地容纳命令式代码。
2. JSP Model 2
- 在 Model 1 中,你可以对 JSP 页面上的内容进行模块和职责的划分,但是由于它们都在一个页面上,物理层面上可以说是完全耦合在一起,因此模块化和单一职责无从谈起。和 Model 1 相比,Model 2 做了明显的改进。
- JSP 只用来做一件事,那就是页面渲染,换言之,JSP 从全能先生转变成了单一职责的页面模板;
- 引入 JavaBean 的概念,它将数据库访问等获取数据对象的行为封装了起来,成为业务数据的唯一来源;
- 请求处理和派发的活交到纯 Servlet 手里,它成为了 MVC 的“大脑”,它知道创建哪个 JavaBean 准备好业务数据,也知道将请求引导到哪个 JSP 页面去做渲染。
3. MVC 的一般化
- JSP Model 2 已经具备了 MVC 的基本形态,但是,它却对技术栈有着明确限制——Servlet、JSP 和 JavaBean。今天我们见到的 MVC,已经和实现技术无关了,并且,在 MVC 三层大体职责确定的基础上,其中的交互和数据流动却是有许多不同的实现方式的。
- 不同的 MVC 框架下实现的 MVC 架构不同,有时即便是同一个框架,不同的版本之间其 MVC 架构都有差异(比如 ASP.NET MVC),在这里我只介绍最典型的两种情况,如果你在学习的过程中见到其它类型,请不要惊讶,重要的是理解其中的原理。
第一种:
- 上图是第一种典型情况,这种情况下,用户请求发送给 Controller,而 Controller 是大总管,需要主动调用 Model 层的接口去取得实际需要的数据对象,之后将数据对象发送给需要渲染的 View,View 渲染之后返回页面给用户。
- 在这种情况下,Controller 往往会比较大,因为它要知道需要调用哪个 Model 的接口获取数据对象,还需要知道要把数据对象发送给哪个 View 去渲染;View 和 Model 都比较简单纯粹,它们都只需要被动地根据 Controller 的要求完成它们自己的任务就好了。
第二种:
- 上图是第二种典型情况,请和第一种比较,注意到了区别没有?这种情况在更新操作中比较常见,Controller 调用 Model 的接口发起数据更新操作,接着就直接转向最终的 View 去了;View 会调用 Model 去取得经过 Controller 更新操作以后的最新对象,渲染并返回给用户。
- 在这种情况下,Controller 相对就会比较简单,而这里写操作是由 Controller 发起的,读操作是由 View 发起的,二者的业务对象模型可以不相同,非常适合需要 CQRS(Command Query Responsibility Segregation,命令查询职责分离)的场景,我在 [第 08 讲] 中会进一步介绍 CQRS。
4. MVC 的变体
- MVC 的故事还没完,当它的核心三层和它们的基本职责发生变化,这样的架构模式就不再是严格意义上的 MVC 了。这里我介绍两种 MVC 的变体:MVP 和 MVVM。
- MVP 包含的三层为 Model、View 和 Presenter,它往往被用在用户的界面设计当中,和 MVC 比起来,Controller 被 Presenter 替代了。
- Model 的职责没有太大的变化,依然是业务数据的唯一来源。
- View 变成了纯粹的被动视图,它被动地响应用户的操作来触发事件,并将其转交给 Presenter;反过来,它的视图界面被动地由 Presenter 来发起更新。
- Presenter 变成了 View 和 Model 之间的协调者(Middle-man),它是真正调度逻辑的持有者,会根据事件对 Model 进行状态更新,又在 Model 层发生改变时,相应地更新 View。
- MVVM 是在 MVP 的基础上,将职责最多的 Presenter 替换成了 ViewModel,它实际是一个数据对象的转换器,将从 Model 中取得的数据简化,转换为 View 可以识别的形式返回给 View。View 和 ViewModel 实行双向绑定,成为命运共同体,即 View 的变化会自动反馈到 ViewModel 中,反之亦然。
总结
- MVC 的几种形式和变体。
- JSP Model 1:请求处理的整个过程,全部都耦合在 JSP 页面里面完成;
- JSP Model 2:MVC 分别通过 JavaBean、JSP 和 Servlet 解耦成三层;
- MVC 的常见形式一:数据由 Controller 调用 Model 来准备,并传递给 View 层;
- MVC 的常见形式二:Controller 发起对数据的修改,在 View 中查询修改后的数据并展示,二者分别调用 Model;
- MVP:Presenter 扮演协调者,对 Model 和 View 实施状态的更新;
- MVVM:View 和 ViewModel 实行数据的双向绑定,以自动同步状态。
你知道的越多,你不知道的越多。
相关文章:

MVC框架
文章目录 JSP 和 ServletMVC 的演进1. JSP Model 12. JSP Model 23. MVC 的一般化4. MVC 的变体 总结 JSP 和 Servlet 如果你有使用 Java 作为主要语言开发网站的经历,那么你一定听过别人谈论 JSP 和 Servlet。其中,Servlet 指的是服务端的一种 Java 写…...

学习笔记之——3D Gaussian Splatting及其在SLAM与自动驾驶上的应用调研
之前博客介绍了NeRF-SLAM,其中对于3D Gaussian Splatting没有太深入介绍。本博文对3D Gaussian Splatting相关的一些工作做调研。 学习笔记之——NeRF SLAM(基于神经辐射场的SLAM)-CSDN博客文章浏览阅读967次,点赞22次࿰…...
Github Copilot 的使用方法和快捷键
Github Copilot是一个基于人工智能技术的代码自动补全工具,它可以为开发者提供实时的代码建议和自动生成代码片段。本文将详细介绍如何安装、设置和使用Github Copilot,并提供一些常用的快捷键来提高开发效率。 1. 安装和设置 1.1 下载并安装VS Code …...
开源iMES工厂管家 - 详细安装部署指南(图解)- 全网独稿
目录 一、服务器环境: 二、部署构成总览: 三、下载 node-v16.17.1-win-x64:Index of /download/release/v16.17.1/ 四、绿色安装 node-v16.17.1-win-x64 五、配置环境变量 六、检查 node-v16.17.1-win-x64 是否成功 七、执行命令组,安装组库与各种依赖 vue3环境配置…...

Codeforces Round 919 (Div. 2)
Problem - A - Codeforces n个约束条件 a x 求出满足n个约束条件的整数的个数 大于等于x,取最大的 小于等于x,取最小的 然后不等于x的,记录在区间范围内的个数,减去这些 #include<bits/stdc.h> #define endl \n #define …...

面向经验丰富的开发人员的最佳 Linux 发行版
在深入研究最佳 Linux 发行版之前,让我们回顾一下历史。到 2021 年,Linux 操作系统已经有 30 年的历史了,从作为开发者 Linus Torvalds 的个人项目开始,它已经走过了很长一段路。最初发布时,其源代码被分发给用户&…...

Rust-借用检查
Rust语言的核心特点是:在没有放弃对内存的直接控制力的情况下,实现了内存安全。 所谓对内存的直接控制能力,前文已经有所展示:可以自行决定内存布局,包括在栈上分配内存,还是在堆上分配内存;支…...

xcode安装及运行源码
抖音教学视频 目录 1、xcode 介绍 2、xcode 下载 3、xocde 运行ios源码 4、快捷键 1、xcode 介绍 Xcode 是运行在操作系统Mac OS X上的集成开发工具(IDE),由Apple Inc开发。Xcode是开发 macOS 和 iOS 应用程序的最快捷的方式。Xcode 具有…...

x-cmd pkg | czg - git commit 智能生成工具
目录 简介首次用户功能特点竞品和相关作品进一步探索 简介 czg 源于 commitizen/cz-cli 交互插件中 cz-git 的延伸项目,重新使用 TypeScript 编写的零依赖独立的 Node.js 命令行工具。旨在使用交互友好的方式,辅助用户生成规范的 git commit message 约…...
Go的并发练习题目
经典并发题目 现在有4个协程,分别对应编号为1,2,3,4,每秒钟就有一个协程打印自己的编号,要求编写一个程序,让输出的编号总是按照1,2,3,4,1,2,3,4这样的规律一直打印下去 type Token struct { }func newWorker(id int, ch chan Token, nextC…...

Python 网络编程之粘包问题
【一】粘包问题介绍 【1】粘包和半包 粘包: 定义: 粘包指的是发送方发送的若干个小数据包被接收方一次性接收,形成一个大的数据包。原因: 通常是因为网络底层对数据传输的优化,将多个小数据包组合成一个大的数据块一次…...

旧衣回收小程序搭建:降低企业成本,提高回收效率!
在人们环保意识提升下,旧衣回收行业受到了大众的关注,同时旧衣回收具有门槛低、利润大的优势。在我国,回收行业不仅帮助普通人就业获利,还对环保做出了较大贡献。因此,旧衣回收行业成为了当下的热门商业模式࿰…...

Jmeter后置处理器——JSON提取器
目录 1、简介 2、使用步骤 1)添加线程组 2)添加http请求 3) 添加JSON提取器 1、简介 JSON是一种简单的数据交换格式,允许互联网应用程序快速传输数据。JSON提取器可以从JSON格式响应数据中提取数据、简化从JSON原始数据中提取特定…...

[SWPUCTF 2022 新生赛]奇妙的MD5
[SWPUCTF 2022 新生赛]奇妙的MD5 wp 题目页面: 提示:可曾听过ctf 中一个奇妙的字符串。 奇妙的字符串 奇妙的字符串,又跟 MD5 有关,我只知道两个: 一个是 MD5 加密后弱比较等于自身,这个字符串是 0e215…...

MHFormer 论文解读
目录 Multi-Hypothesis Transformer 结果 Introduction & Related work 多假设 为什么作者提出这个模型? 3.Multi-Hypothesis Transformer 3.1 Preliminary 3.2 MultiHypothesis Generation 3.3 Temporal Embedding 3.4. SelfHypothesi…...
Python列表append()函数使用详解
在Python中,列表是一种可变序列类型,可以用来存储多个元素。列表的append()函数是用于在列表末尾添加新元素的内置方法。本文将详细介绍Python列表的append()函数及其使用方法。 一、append()函数的基本语法 append()函数的语法非常简单,只…...

第08章_面向对象编程(高级)拓展练习(关键字:static,代码块,关键字:final,抽象类和抽象方法,接口,内部类,枚举类,注解,包装类)
文章目录 第08章_面向对象编程(高级)拓展练习01-关键字:static1、银行账户类2、图形类3、数组工具类4、二分查找5、二分查找6、素数7、阅读代码,分析运行结果8、阅读代码,分析运行结果 02-代码块9、阅读代码࿰…...

分布式光伏运维平台在提高光伏电站发电效率解决方案
摘要:伴随着能源危机和环境恶化问题的日益加重,科技工作者进一步加大对新能源的开发和利用。太阳能光伏发电作为新型清洁能源的主力军,在实际生产生活中得到了广泛的应用。然而,光伏发电效率偏低,成为制约光伏发电发展…...

2024.1.14~1.20 周内刷题总结
2024.1.14~1.20 周内刷题总结 [ABC158F] Removing Robots 题解[ABC145F] Laminate 题解[ABC254G] Elevators 题解(坑点总结)[ARC160C] Power Up 题解[ABC203F] Weed 题解Shopping时代的眼泪 [ABC158F] Removing Robots 题解 \qquad 题面 \qquad 本题的连…...

徐州数字孪生元宇宙赋能工业智能制造,助力传统制造业数字化转型
徐州数字孪生元宇宙赋能工业智能制造,助力传统制造业数字化转型。在徐州市制造业企业数字化转型的过程中,数字孪生技术的应用已经取得了显著成效。一方面,企业的生产效率得到了显著提高,产品质量也得到了有效保障。另一方面&#…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...