javaweb学习(day07-手动实现tomcat)

一、引入案例

1 小案例

引出对 Tomcat 底层实现思考

1.1 完成小案例

1.1.1 运行效果

1.2 maven简要介绍 

我们准备使用 Maven 创建一个 WEB 项目 , 简单给小伙伴介绍一下 Maven
, 更加详细的使用,我们还会细讲 , 现在先使用一把

 

1.3 创建maven的web项目

 完成后,如果目录没有出现src,不要慌,自行百度搜索解决方案

1.4 配置阿里 maven 镜像

 

1.5 修改 pom.xml 

<?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.hspedu</groupId><artifactId>tomcat02</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>tomcat02 Maven Webapp</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!--  引入servlet的依赖1. dependency 表示依赖, 也就是我们这个项目需要依赖的 jar 包2. groupId 和 artifactId 被统称为坐标, 是为了去定位这个项目/jar3. groupId: 一般是公司 比如 com.baidu , 这里是 avax.servlet4. artifactId 一般是项目名, 这里是 javax.servlet-api5. 这样的化就可以定位一个 jar 包6. version 表示你引入到我们项目的 jar 包的版本是 3.1.07. scope: 表示作用域,也就是你引入的 jar 包的作用范围8. provided 表示在 tomcat 本身是有这个 jar 的,因此在编译,测试使用,但是在打包发布就不用要带上9. 在默认情况下, 引入的 jar 会到 中央仓库去下载 https://mvnrepository.com/10. 会下载到哪里到你指定的目录 C:\Users\Administrator\.m2\repository11. 有时为了下载更快, 往往配置镜像,12. 在 默 认 的 路 径 下 拷 贝 一 份 setting.xml 到C:\Users\Administrator\.m2\settings.xml13. 指定默认的阿里云镜像--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency></dependencies><build><finalName>tomcat02</finalName><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin></plugins></pluginManagement></build>
</project>

 1.7 cal.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>计算器</title>
</head>
<body>
<h1>计算器</h1>
<form action="/calServlet" method="get">num1:<input type="text" name="num1"><br/>num2:<input type="text" name="num2"><br/><input type="submit" value="提交">
</form>
</body>
</html>

1.8 创建 java 目录,存放 java 源文件

1.9 创建 CalServlet.java 

package com.hspedu.servlet;import com.hspedu.utils.WebUtils;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;public class CalServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//接收提交的数据进行计算String strnum1 = request.getParameter("num1");String strnum2 = request.getParameter("num2");//把strnum1和strnum2转成intint num1= WebUtils.parseIt(strnum1,0);int num2=WebUtils.parseIt(strnum2,0);int result=num1+num2;response.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();writer.print("<h1>"+num1+" + "+num2+" = "+result+"<h1>");writer.flush();writer.close();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}
}

 1.10 修改 web.xml , 配置 Servlet

 1.11 具类

package com.hspedu.utils;public class WebUtils {public static int parseIt (String strNum,int defaultVal){try {return Integer.parseInt(strNum);} catch (NumberFormatException e) {System.out.println(strNum+" 格式不对,转换失败");return defaultVal;}}
}

没有配置tomcat记得配置哦,

我们的目标 : 不用 Tomcat, 不用系统提供的 Servlet, 模拟 Tomcat 底层实现并能调用我
们自己设计的 Servle, 也能完成相同的功能

二、 Tomcat 整体架构分析

1 一图胜千言

  • 说明: Tomcat 有三种运行模式(BIO, NIO, APR, 因为核心讲解的是 Tomcat 如何接收客户端请求,解析请求, 调用 Servlet , 并返回结果的机制流程, 采用 BIO 线程模型来模.[绘图]

 

三、实现 

1 实现任务阶段 1 

编写自己 Tomcat, 能给浏览器返回 Hi, Hspedu 

1.1 基于 socket 开发服务端-流程 

 1.2 需求分析/图解

需求分析如图, 浏览器请求 http://localhost:8080/??, 服务端返回 hi , hspedu

1.3 分析+代码实现 

1.3.1 分析示意图 
 1.3.2 代码实现
package com.hspedu.tomcat;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;/*
这是第一个版本的tomcat,可以完成接收浏览器的请求,并返回信息*/
public class LinranTomcatV1 {public static void main(String[] args) throws IOException {//1.创建ServerSocket serverSocket=new ServerSocket(8080);System.out.println("服务器正在8080端口监听");while (!serverSocket.isClosed()){//等待浏览器/客户端的链接//如果有连接,就创建一个socket//这个socket就是服务器和浏览器的连接通道Socket socket=serverSocket.accept();//先接收浏览器发送的数据//inputStream是字节流=》BufferedReader(字符流)InputStream inputStream = socket.getInputStream();BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"utf-8"));//接收到浏览器发送的数据System.out.println("==============接收到浏览器发送的数据==============");String mes=null;//循环读取while ((mes=bufferedReader.readLine())!=null){if(mes.length()==0){break;//退出}System.out.println(mes);}//我们的tomcat回送数据OutputStream outputStream = socket.getOutputStream();//构建一个 http 响应的头//\r\n 表示换行//http 响应体,需要前面有两个换行 \r\n\r\nString respHeader = "HTTP/1.1 200 OK\r\n" +"Content-Type: text/html;charset=utf-8\r\n\r\n";String resp = respHeader + "hi, hspedu 韩顺平教育";System.out.println("========我们的 tomcat 给浏览器会送的数据 ======");System.out.println(resp);outputStream.write(resp.getBytes());//将 resp 字符串以 byte[] 方式返回//关闭outputStream.flush();outputStream.close();inputStream.close();socket.close();}}
}

 问题分析:没有使用 BIO 线程模型,没有实现多线程,性能差

实现任务阶段 2 

使用 BIO 线程模型,支持多线程

2.1 BIO 线程模型介绍 

2.2 需求分析/图解 

浏览器请求 http://localhost:8080, 服务端返回 hi , hspedu, 后台 hsptomcat 使用 BIO 线程模型 , 支持多线程 => 对前面的开发模式进行改造

 2.3 分析+代码实现

2.3.1 分析示意图 

2.3.2 代码实现 

新建一个线程类

package com.hspedu.tomcat.handler;
/*HspRequestHandler对象是一个线程对象处理http请求的*/import java.io.*;
import java.net.Socket;public class HspRequestHandler implements Runnable {//定义一个socketprivate Socket socket=null;public HspRequestHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {//这里我们可以对客户端/浏览器进行通信try {InputStream inputStream = socket.getInputStream();//把inputStream->bufferedReaderBufferedReader bufferedReader =new BufferedReader(new InputStreamReader(inputStream, "utf-8"));String mes;System.out.println("=============HspRequestHandler接收的信息如下=================");while ((mes=bufferedReader.readLine())!=null){if(mes.length()==0){break;}System.out.println(mes);}//返回数据给我们的浏览器->封装成http响应OutputStream outputStream = socket.getOutputStream();//构建http响应String respHeader = "HTTP/1.1 200 OK\r\n" +"Content-Type: text/html;charset=utf-8\r\n\r\n";String resp = respHeader + "hi, hspedu 韩顺平教育";System.out.println("========我们的 tomcat 给浏览器会送的数据 ======");System.out.println(resp);outputStream.write(resp.getBytes());//将 resp 字符串以 byte[] 方式返回outputStream.flush();outputStream.close();inputStream.close();socket.close();} catch (IOException e) {e.printStackTrace();} finally {//最后一定确保socket要关闭if(socket!=null){try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}
}

 主程序

package com.hspedu.tomcat;import com.hspedu.tomcat.handler.HspRequestHandler;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class LinranTomcatV2 {public static void main(String[] args) throws IOException {ServerSocket serverSocket=new ServerSocket(8080);System.out.println("============LinranTomcatV2在8080监听===============");while (!serverSocket.isClosed()){//只要serverSocket没有关闭,就一直等待连接Socket socket = serverSocket.accept();//这个socket就是一个通信//创建一个线程对象,并把socket给该线程new Thread( new HspRequestHandler(socket)).start();}}
}

3 实现任务阶段

处理 Servlet

3.1 Servlet 生命周期-回顾

3.2 需求分析/图解 

 3.3 分析

 代码实现参考视频和项目源码

很心塞的一点,在跟着学习的过程中,最终 报错了,很烦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726787.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多个变量指向同一个数组

多个变量中的内存地址是一样的&#xff0c;都是指向当前的数组&#xff0c;存储当前数组对象的地址&#xff0c;因此修改是对当前数组的值进行修改 数组中存储的是null&#xff0c;那么他将不会指向任何数组对象 System.out.println(arr) 输出结果为null&#xff0c;里面没有…

Vue+OpenLayers7入门到实战:webgl图层叠加大量Icon图片到地图,解决叠加超大数据量图片导致浏览器卡住变慢的问题

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7 前言 之前已经讲了如何地图中如何添加大量点到webgl图层优化大量点浏览器页面卡顿的问题。本章介绍补充一下叠加大量图片图标要素到地图的情况下的问题。 二、依赖和使用 "ol": "7.5.2"使用npm安装依…

Vue+OpenLayers7入门到实战:OpenLayers7如何使用gifler库来实现gif动态图图片叠加到地图上

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7 前言 OpenLayers7本身不支持gif图片作为图标要素显示到地图上,所以需要通过其他办法来实现支持gif图片。 本章介绍如何使用OpenLayers7在地图上使用gifler库先生成canvas画板,然后通过canvas画板的重绘事件来重新渲染地图…

leetcode 热题 100_最大子数组和

题解一&#xff1a; 动态规划&#xff1a;这是一道经典的动态规划题。维护一个dp数组&#xff0c;dp[i]表示0~i组成的数组的最大子数组和。当数组长度为1时&#xff0c;最大和连续子数组是它本身&#xff0c;也就是dp[i]nums[i]。当数组长度每增加1时&#xff0c;最大和连续子数…

LVGL在VScode中安装模拟器运行配置笔记教程

1、LVGL模拟器工程搭建 LVGL(Light and Versatile Graphics Library,轻巧而多功能的图形库)是一个免费的开放源代码图形库,它提供创建具有易于使用的图形元素,精美的视觉效果和低内存占用的嵌入式GUI所需的一切。本文主要讲述如何实现在VScode中实现LVGL模拟器环境的搭建运行。…

遗传算法理解与代码实战(一)- demo(python手写代码)

遗传算法&#xff08;Genetic Algorithm, GA&#xff09;是模拟自然界中生物进化的机制来搜索最优解的方法。遗传算法属于进化计算的一部分&#xff0c;它借鉴了达尔文的自然选择和孟德尔的遗传学原理。 1、算法背景 遗传算法的灵感来源于生物进化过程。在自然界中&#xff0…

Linux CentOS系统安装Spug并结合内网穿透实现远程访问本地运维平台

目录 前言 1. Docker安装Spug 2 . 本地访问测试 3. Linux 安装cpolar 4. 配置Spug公网访问地址 5. 公网远程访问Spug管理界面 6. 固定Spug公网地址 结语 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊Linux CentOS系统安装Spug并结合…

Upload 上传(图片/文件),回显(图片),下载(文件)

1.前端技术&#xff1a;V3 Ant Design Vue 2.后端技术&#xff1a;Java 图片上传/回显&#xff1a; 文件上传回显&#xff1a; 表结构&#xff1a;单文件/图片上传为A表对文件C表 &#xff08;A表field字段 对应 C表id字段&#xff09; 如图&#xff1a;A表中的 vehicle_d…

OracleXE112、plsqldev1207的安装和基本配置

OracleXE112、plsqldev1207的安装和基本配置 OracleXE112、plsqldev1207的安装和基本配置Oracle安装oracle是什么Oracle两个版本下载安装包 安装OracleXE112_Win64注意&#xff1a;安装到空目录下&#xff1b;输入口令&#xff08;记住啊&#xff01;&#xff09;安装成功&…

【b站咸虾米】ES6 Promise的用法,ES7 async/await异步处理同步化,异步处理进化史

课程地址&#xff1a;【ES6 Promise的用法&#xff0c;ES7 async/await异步处理同步化&#xff0c;异步处理进化史】 https://www.bilibili.com/video/BV1XW4y1v7Md/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 图文地址&#xff1a;https://www.b…

HarmonyOS NEXT应用开发案例——滑动页面信息隐藏与组件位移效果

介绍 在很多应用中&#xff0c;向上滑动"我的"页面&#xff0c;页面顶部会有如下变化效果&#xff1a;一部分信息逐渐隐藏&#xff0c;另一部分信息逐渐显示&#xff0c;同时一些组件会进行缩放或者位置移动。向下滑动时则相反。 效果图预览 使用说明 向上滑动页面…

Django Web架构:全面掌握Django模型字段(上)

Django Web架构 全面掌握Django模型字段&#xff08;上&#xff09; - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article…

网络信息安全:nginx漏洞收集(升级至最新版本)

网络&信息安全&#xff1a;nginx漏洞收集&#xff08;升级至最新版本&#xff09; 一、风险详情1.1 nginx 越界写入漏洞(CVE-2022-41742)1.2 nginx 缓冲区错误漏洞(CVE-2022-41741)1.3 nginx 拒绝服务漏洞&#xff08;CNVD-2018-22806&#xff09; 二、nginx升级步骤 &…

每日一练 | 华为认证真题练习Day194

1、下面是路由器Huawei的部分输出配置&#xff0c;关于该部分配置描迷正确的是: [huawei] bgp 100 [huawei-bgp]peer 12.12.12.2 ip-prefix P1 export [huawei]ip-prefix P1 index 5 deny 10.0.0.0 0 greater-equal 8 less-equal 32 [huawei]ip-prefix P1 index 5 deny 172…

Vue开发环境构建

相关依赖 1.安装Node https://nodejs.org/en/ 验证是否安装 λ node -v v20.10.0 2.安装cnpm镜像 npm install -g cnpm --registryhttps://registry.npm.taobao.org 3.webpack:构建工具 4.开发工具vscode 安装插件&#xff1a;扩展-搜索vetur,vscode-icon,chinese, 搭…

上门预约平台有哪些优势和特点

在着手开发之前&#xff0c;市场调研是不可或缺的步骤。它能帮助我们深入了解当前上门按摩市场的供需状况及竞争态势&#xff0c;进而挖掘潜在用户的真实需求和期望。这些宝贵的信息将成为我们塑造产品特性和锁定目标用户群体的关键。 紧接着&#xff0c;根据市场调研的反馈&am…

Java | Java的输入与输出

文章目录 Java输出1、System.out.println()2、System.out.printf()3、System.out.print() Java输入1、使用Scanner类的对象获取输入&#xff08;1&#xff09;一般类型输入&#xff08;2&#xff09;字符串类型输入&#xff08;3&#xff09;char类型输入 2、使用System.in.rea…

鸿蒙NEXT实战开发:【截屏】

展示全屏截图和屏幕局部截图。通过[screenshot]模块实现屏幕截图 &#xff0c;通过[window]模块实现隐私窗口切换&#xff0c;通过[display]模块查询当前隐私窗口。 效果预览 全屏截图局部截图选择区域局部截图 使用说明&#xff1a; 点击右上角图标打开弹窗&#xff0c;选…

江苏某机场多座超高端智慧公厕上线

作为行业信息化程度最高的智慧机场综合管理系统&#xff0c;能为旅客、航空公司以及机场自身的业务管理提供及时、准确、系统、完整的信息服务&#xff0c;达到信息高度统一、共享、调度严密、管理先进和服务优质的目的。而其中的智慧卫生间建设&#xff0c;更是提升机场旅客服…