当前位置: 首页 > news >正文

MVC框架简易实现【精细】

目录

mvc 的架构

MVC 框架

传统web开发的弊端

1.创建一个maven项目

2.添加maven依赖

3.创建TomCatService类

        3.1 创建TomcatService类

        3.2 TomcatService类讲解

        3.3 安装项目到本地仓库,给其他项目使用

4.测试启动Tomcat

         4.1 创建一个新的maven项目

        4.2 引用mvc-framework项目的依赖

         4.3 创建一个webapp包,里面在创建index.html文件

         4.4 创建一个测试类

        4.5 启动项目

        4.6 访问项目


mvc 的架构

model     ----------> 业务领域的核心对象(Entity,Service,Dao)

View       ----------> 视图层,做数据的提交和渲染 (JSP、HTML.........)

Controller --------> 控制层,专门用于处理Http请求(Servlet)


MVC 框架

简化控制层以及视图渲染的操作,将这些API进行更高层封装,使用起来更加简便,可以隐藏Servlet的操作,同时还可以提供简便的部署方式。


传统web开发的弊端

1.每一个请求都必须要有一个对应的Servlet去处理:

                在传统的Servlet开发中,每个请求都需要对应一个Servlet类来处理。这导致了项目结构的臃肿,且难以维护和扩展。特别是对于大型项目,Servlet的数量可能会非常庞大,给代码的管理和维护带来挑战


2.请求参数的处理相对繁琐 :

                在Servlet开发中,通常需要手动解析请求参数,包括从URL中解析参数或者从请求体中读取参数。这样的处理方式相对繁琐,容易出错,尤其是在处理复杂的参数结构时更加困难。


3.请求响应的统一性比较繁杂:

                在Servlet开发中,通常需要手动设置响应的内容类型、编码等信息,并且手动编写响应内容。这样的操作需要开发者自行管理,容易导致响应的不一致性,增加了维护成本。


4.部署Web应用相对繁杂,肯能存在缓存的问题:

                在传统的Servlet开发中,部署Web应用通常需要手动将Servlet类部署到Servlet容器中,并且需要手动处理依赖关系、配置信息等。这样的部署方式相对繁琐,容易出错。此外,由于Servlet容器会缓存Servlet类,当修改了Servlet类但未正确地刷新缓存时,可能会导致旧版本的Servlet类被执行,从而引发一系列问题。

 为了解决这传统web开发的弊端,我们自己写一个MVC框架简易实现


1.创建一个maven项目


2.添加maven依赖

对应的依赖为:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xr</groupId><artifactId>mvc-framework</artifactId><version>0.9</version><!--打包方式为jar--><packaging>jar</packaging><properties><!--maven编译源代码的jdk版本--><maven.compiler.source>21</maven.compiler.source><!--maven编译目标代码的jdk版本--><maven.compiler.target>21</maven.compiler.target><!--项目构建编码格式--><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--Tomcat依赖--><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>10.1.19</version></dependency><!--JSP解析器依赖--><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><version>10.1.19</version></dependency><!--EL表达式依赖--><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-el</artifactId><version>10.1.19</version></dependency><!--servlet依赖--><dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.0.0</version><!--这个依赖是运行环境提供的,不需要打包到jar中--><scope>provided</scope></dependency><!--yml文件解析器--><dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.33</version></dependency><!--底层工具库(Guava,Hutool)--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.27</version></dependency></dependencies></project>

注意:

        1.这里的项目打包方式一定是jar

        2.servlet依赖范围一定是provided

                如果不是Provided,当其他项目引用这个项目的依赖,那么这个依赖会打包到jar中,而Tomcat自带Servlet,那么tomcat会识别到这个jar中的Servlet,tomcat就不知道使用哪个Servlet


3.创建TomCatService类

        3.1 创建TomcatService类

作用:

        启动一个嵌入式的Tomcat服务器。在Java Web开发中,通常使用Tomcat作为Servlet容器来运行Web应用,而这个类的目的是通过代码的方式启动一个Tomcat服务器,而不是通过传统的部署方式

       

        3.2 TomcatService类讲解

package com.xr.embed;import cn.hutool.core.io.FileUtil;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;import java.io.File;/*** Tomcat容器* @author xr* @Date 2024/5/13 11:32*/
public class TomcatServer {/*** 容器的端口号*/private final Integer port = 8080;/*** ContextPath路径,默认值是"/",表示项目的根*/private final String contextPath = "/";/*** web资源的部署目录*/private String webRoot = "src/main/webapp";/*** 启动Tomcat服务器*/public void startServer() {// 实例化Tomcat对象Tomcat tomcat = new Tomcat();// 设置端口tomcat.setPort(port);// 将webRoot构建为绝对路径webRoot = FileUtil.getWebRoot().getAbsolutePath()+ File.separator + webRoot;// 设置contextPath和web资源目录tomcat.addWebapp(contextPath, webRoot);// 创建连接tomcat.getConnector();try {//启动tomcattomcat.start();//将Tomcat进行阻状态,保持运行状态tomcat.getServer().await();} catch (LifecycleException e) {throw new RuntimeException("启动Tomcat失败!!!",e);}}
}

属性:

                     port  :     配置Tomcat服务器的端口

        ContextPath :   应用的根路径

              webRoot :   指定了Web资源的部署目录,即Web应用的根目录。在实际运行时,会将这个目录构建为绝对路径,并传递给Tomcat


方法 :

        startServer() :     首先实例化了Tomcat对象,然后设置了端口和Web资源目录。接着,通过调用addWebapp()方法将Web应用部署到Tomcat的ContextPath下。最后,启动了Tomcat服务器并使其保持运行状态

注意 :

           为什么要让Tomcat进入阻塞装填???

        如果Tomcat进入阻塞状态的话,只要一启动,Tomcat就直接结束了,所以要让Tomcat保持运行状态

        3.3 安装项目到本地仓库,给其他项目使用


4.测试启动Tomcat

         4.1 创建一个新的maven项目

        4.2 引用mvc-framework项目的依赖

对应的依赖:

        

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xr</groupId><artifactId>webapp-demo</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>com.xr</groupId><artifactId>mvc-framework</artifactId><version>0.9</version></dependency></dependencies></project>

         4.3 创建一个webapp包,里面在创建index.html文件

有则不用创建,没有则创建

具体代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h2>Hello Tomcat</h2>
</body>
</html>

         4.4 创建一个测试类

具体代码:

package com.xr;import com.xr.embed.TomcatServer;/*** 测试方法* @author xr* @Date 2024/5/13 11:50*/public class Main {public static void main(String[] args) {// 创建TomcatServer对象TomcatServer server = new TomcatServer();// 启动Tomcatserver.startServer();}
}

        4.5 启动项目

项目启动成功!!!!

                之前是要配置了Tomcat才能启动项目,我们这里并没有配置Tomcat

发现 :

        我们并没有在Idea中配置Tomcat,按照之前的方法,我们需要在IDEA中配置Tomcat,而这里所使用的,间接让项目内嵌了Tomcat,所以无需配置Tomcat

        4.6 访问项目

------------------------------------------------------待更新------------------------------------------------------------------

相关文章:

MVC框架简易实现【精细】

目录 mvc 的架构 MVC 框架 传统web开发的弊端 1.创建一个maven项目 2.添加maven依赖 3.创建TomCatService类 3.1 创建TomcatService类 3.2 TomcatService类讲解 3.3 安装项目到本地仓库&#xff0c;给其他项目使用 4.测试启动Tomcat 4.1 创建一个新的maven项目 4.2 引用…...

Java入门基础学习笔记18——赋值运算符

赋值运算符&#xff1a; 就是“”&#xff0c;就是给变量赋值的&#xff0c;从右边往左边看。 int a 10; // 把数据赋值给左边的变量a存储。 扩展赋值运算符&#xff1a; 注意&#xff1a;扩展的赋值运算符隐含了强制类型转换。 package cn.ensource.operator;public class…...

csv 可视化 python代码

excel查看csv后,csv就被锁定了,不能修改,用pyqt写一个csv查看工具,拖拽查看,非常方便 目录 第2版,提升加载速度 选中单元格统计个数,求和,平均值...

HashMap 和 Hashtable区别的底层原理

一、容器键值对&#xff1a; 1.HashMap 的 key 和 value 都允许为 null &#xff0c; HashMap 在 key 为 null 的时候&#xff0c;值必须为null。 2.Hashtable 的 key 和 value 都不允许为 null 。 Hashtable 遇到key或value为 null时 &#xff0c;将抛出 NullPointerException…...

代码随想录35期Day32-Java

Day32题目 LeetCode122.买股票的最佳时机 核心思想&#xff1a;很简单&#xff0c;只要第二天比第一天贵&#xff0c;就第一天买入&#xff0c;第二天卖出 class Solution {public int maxProfit(int[] prices) {// 只要后一天比这一天价钱高就买&#xff0c;然后第二天卖出…...

ROS 2边学边练(45)-- 构建一个能动的机器人模型

前言 在上篇中我们搭建了一个机器人模型(其由各个关节&#xff08;joint&#xff09;和连杆&#xff08;link&#xff09;组成)&#xff0c;此篇我们会通过设置关节类型来实现机器人的活动。 在ROS中&#xff0c;关节一般有无限旋转&#xff08;continuous&#xff09;,有限旋转…...

【第66例】IPD体系进阶:华为IPD发展历程

目录 简介 样例 作者简介 简介 想要引入 IPD,首先就要思考一些问题: 跟我的企业适配吗? 流程会不会太重了? 一定要引入吗,有没有其他方式? 从目前大的环境来说。 中国制造业正在由“中国制造”向“中国创造”转变。 这也是企业价值转移的趋势。 宏碁集团创始人施振…...

websevere服务器从零搭建到上线(四)|muduo网络库的基本原理和使用

文章目录 muduo源码编译安装muduo框架讲解muduo库编写服务器代码示例代码解析用户连接的创建和断开回调函数用户读写事件回调 使用vscode编译程序配置c_cpp_properties.json配置tasks.json配置launch.json编译 总结 muduo源码编译安装 muduo依赖Boost库&#xff0c;所以我们应…...

C语言笔记10

1.用指针打印一维数组 //1.用指针打印一维数组 #include <stdio.h> int main() {//int arr[] { 1,2,3,4,5 };int arr[5] { 0 };int* p &arr[0];int sz sizeof(arr) / sizeof(arr[0]);for (int i 0; i < sz; i){scanf("%d", &arr[i]);}//int* …...

BMS-HiL主要功能

BMS HIL 系统中 PC 机中安装实验管理软件用于测试过程管理和测试序列编辑&#xff0c;通过以太网与 PXI 机箱中的处理器进行连接&#xff0c;处理器中运行实时系统&#xff08;Real Time&#xff09;并安装 Veristand 终端引擎&#xff0c;通过与 PC 中的数据传输&#xff0c;对…...

idea无法识别加载pom.xml文件

有时idea无法识别加载pom.xml文件&#xff0c;直接打开pom.xml文件&#xff0c;然后添加到maven就行...

C语言笔记12

1.使用qsort函数进行排序 #include <stdio.h> #include <stdlib.h> #include <string.h>//void qsort(void* base, //指向待排序数组的第一个元素的指针 // size_t num, //base指向数组中的元素个数 // size_t size,//base指向的数组中一…...

说一下 hibernate 的缓存机制?

Hibernate 的缓存机制是为了提高应用程序的性能&#xff0c;通过减少对数据库物理数据源的访问频次而设计的。Hibernate 的缓存主要可以分为两个级别&#xff1a;一级缓存&#xff08;也称为 Session 级别的缓存&#xff09;和二级缓存&#xff08;也称为 SessionFactory 级别的…...

Mac安装jadx

1、使用命令brew安装 : brew install jadx 输入完命令,等待安装完毕 备注&#xff08;关于Homebrew &#xff09;&#xff1a; Homebrew 是 MacOS 下的包管理工具&#xff0c;类似 apt-get/apt 之于 Linux&#xff0c;yum 之于 CentOS。如果一款软件发布时支持了 homebrew 安…...

风扇开启执行逻辑

执行流程 public static void businessExecutionWork(){//以下为业务逻辑部分System.out.println("1、根据电池包控制风扇服务执行 开始!");//1、获取电池包电压、电流、环境温度//获取电池包电压、电流、环境温度ObtainBatteryDataService obtainBatteryDataServic…...

调用函数实现数组的输入排序插入与输出

输入一串数字&#xff0c;输出排序插入后输出最后的数字序列&#xff1b; 把主要步骤交给主函数&#xff0c;通过调用函数来实现整体的功能&#xff1a; 写出主函数&#xff08;这里使用冒泡排序&#xff09;&#xff1a; int main(){int n;int a[10];cin>>n;inputa(a…...

代码随想录算法训练营Day 41| 动态规划part03 | 343. 整数拆分、96.不同的二叉搜索树

代码随想录算法训练营Day 41| 动态规划part03 | 343. 整数拆分、96.不同的二叉搜索树 文章目录 代码随想录算法训练营Day 41| 动态规划part03 | 343. 整数拆分、96.不同的二叉搜索树343. 整数拆分一、动态规划二、贪心&#xff08;不需要掌握&#xff09; 96.不同的二叉搜索树一…...

多模态产品在智能文档处理应用的展望------以TextIn模型为例

前言发展现状TextIn 文档解析技术文本向量化展望合合信息 前言 第十四届视觉与学习青年学者研讨会(VALSE 2024)于5月5日-7日在山城重庆渝北区悦来国际会议中心举办。大会聚焦计算机视觉、模式识别、多媒体和机器学习等领域的国际前沿和热点方向。大会中&#xff0c;合合信息智能…...

上海市计算机学会竞赛平台2024年3月月赛丙组最近的数字

题目描述 给定两个正整数 &#x1d45b;n 与 &#x1d451;d &#xff0c;请找到所有最接近 &#x1d45b;n 且是 &#x1d451;d 的倍数的整数。 输入格式 第一行&#xff1a;单个整数表示 &#x1d45b;n第二行&#xff1a;单个整数表示 &#x1d451;d 输出格式 若干行…...

RFID在汽车制造中的应用如何改变行业

随着工业4.0和中国制造2025的推进&#xff0c;企业对于智能化、自动化的需求日益增长&#xff0c;RFID射频技术在制造业中已经相当普遍了。在如今这瞬息万变的行业与时代中&#xff0c;RFID技术可以帮助企业获得竞争优势&#xff0c;简化日益复杂的生产流程&#xff0c;推动企业…...

【Nginx】Nginx index 指令全解:从首页加载失败到高性能目录服务的生产实践

Nginx index 指令全解:从首页加载失败到高性能目录服务的生产实践 本文面向已部署过简单 Nginx 服务、了解反向代理概念,但尚未系统掌握其静态文件目录索引与默认首页机制的中高级工程师。我们将彻底拆解 index 指令的工作原理、继承规则、与 try_files 的协作边界,揭示为何…...

AltSnap:重新定义Windows窗口管理效率的革命性工具

AltSnap&#xff1a;重新定义Windows窗口管理效率的革命性工具 【免费下载链接】AltSnap Maintained continuation of Stefan Sundins AltDrag 项目地址: https://gitcode.com/gh_mirrors/al/AltSnap 你是否曾经在Windows系统中为繁琐的窗口操作而烦恼&#xff1f;当需要…...

Docker Compose部署Nginx Proxy Manager保姆级教程:从端口映射到数据持久化全解析

Docker Compose部署Nginx Proxy Manager全流程精解&#xff1a;从架构设计到生产级实践 当你面对数十个需要反向代理的服务时&#xff0c;手动编辑Nginx配置文件的繁琐程度足以让人望而生畏。Nginx Proxy Manager的出现彻底改变了这种局面——这个基于Docker的开源解决方案将复…...

Floquet量子码的动态纠错与时空同步技术解析

1. Floquet量子码的时空同步原理在量子纠错领域&#xff0c;Floquet码代表了一种通过周期性测量实现动态稳定的新型编码方案。与传统静态量子纠错码不同&#xff0c;Floquet码的核心创新在于将时间维度纳入编码结构&#xff0c;形成时空一体的纠错机制。这种动态特性使其在容错…...

STM32F4智能灯光控制系统实战:LVGL界面、传感器与MQTT物联网开发

1. 项目概述与核心价值最近在整理手头的嵌入式项目&#xff0c;翻出来一个基于STM32F4的智能灯光控制系统&#xff0c;感觉挺有代表性的。这个项目麻雀虽小&#xff0c;五脏俱全&#xff0c;它把单片机控制、传感器数据采集、GUI界面开发&#xff08;LVGL&#xff09;、物联网通…...

3个关键步骤解锁Switch隐藏功能:TegraRcmGUI图形化注入工具完整指南

3个关键步骤解锁Switch隐藏功能&#xff1a;TegraRcmGUI图形化注入工具完整指南 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI 想为你的Nintendo Switch解锁…...

开源写作助手:本地化部署的智能文本分析与AI辅助创作工具

1. 项目概述&#xff1a;一个为写作者量身定制的智能工具箱如果你经常需要写点东西&#xff0c;无论是技术文档、博客文章、工作报告&#xff0c;还是小说草稿&#xff0c;大概率都经历过这样的时刻&#xff1a;对着空白文档发呆&#xff0c;感觉大脑一片空白&#xff1b;或者写…...

避坑指南:SAP BP客户维护cl_md_bp_maintain的那些“坑”与最佳实践

SAP BP客户维护实战&#xff1a;cl_md_bp_maintain深度避坑手册 当ABAP开发人员第一次接触cl_md_bp_maintain类时&#xff0c;往往会被其强大的业务伙伴(Business Partner)管理功能所吸引&#xff0c;但随之而来的是一系列令人头疼的"坑"。本文将从实际项目经验出发&…...

蓝桥杯备赛:那些教科书里没写的“潜规则”与实战优化

1. 那些容易被忽视的编译细节 参加过蓝桥杯的同学都知道&#xff0c;比赛中最让人崩溃的不是题目有多难&#xff0c;而是明明本地运行好好的代码&#xff0c;提交后却莫名其妙地编译失败。这些坑我在第一次参赛时几乎全踩过&#xff0c;现在回想起来都是血泪教训。 首先是main函…...

移动篇:WMS里的“乾坤大挪移”——移库、补货、冻结全解析

WMS里的“乾坤大挪移”——移库、补货、冻结全解析 摘要&#xff1a;货物入库后&#xff0c;不是“一放了之”。库位要优化、库存要周转、临期品要管理……这就涉及WMS中的“库存移动”操作。移库、补货、冻结分别解决什么问题&#xff1f;什么场景下会用到&#xff1f;本文带你…...