Tomcat的架构图

 
              图三:Tomcat Server处理一个HTTP请求的过程

处理HTTP请求过程

假设来自客户的请求为:http://localhost:8080/test/index.jsp 请求被发送到本机端口8080

1、用户点击网页内容,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得。 
2、Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的回应。 
3、Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host。 
4、Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有的Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理)。 
5、path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL PATTERN为*.jsp的Servlet,对应于JspServlet类。 
6、构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost().执行业务逻辑、数据存储等程序。 
7、Context把执行完之后的HttpServletResponse对象返回给Host。 
8、Host把HttpServletResponse对象返回给Engine。 
9、Engine把HttpServletResponse对象返回Connector。 
10、Connector把HttpServletResponse对象返回给客户Browser。

简单模拟Tomcat

  tomcat是通过socket和浏览器获得连接,因为可能有多个请求,所以要用到多线程去接收,通过io流来传递数据。   

package Server;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.StringTokenizer;
public class TomcatServer {private final static int PORT = 8080;public static void main(String[] args) {try {ServerSocket server = new ServerSocket(PORT);// 根据端口号启动一个serverSocketServletHandler servletHandler = new ServletHandler(server);servletHandler.start();} catch (Exception e) {e.printStackTrace();}}private static class ServletHandler extends Thread {ServerSocket server = null;public ServletHandler(ServerSocket server) {this.server = server;}@Overridepublic void run() {while (true) {try {Socket client = null;client = server.accept();// ServerSocket阻塞等待客户端请求数据if (client != null) {try {System.out.println("接收到一个客户端的请求");// 根据客户端的Socket对象获取输入流对象。// 封装字节流到字符流BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));// GET /test.jpg /HTTP1.1// http请求由三部分组成,分别是:请求行、消息报头、请求正文。// 这里取的第一行数据就是请求行。http协议详解可以参考http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html说的很详细String line = reader.readLine();System.out.println("line: " + line);// 拆分http请求路径,取http需要请求的资源完整路径String resource = line.substring(line.indexOf('/'), line.lastIndexOf('/') - 5);System.out.println("the resource you request is: " + resource);resource = URLDecoder.decode(resource, "UTF-8");// 获取到这次请求的方法类型,比如get或post请求String method = new StringTokenizer(line).nextElement().toString();System.out.println("the request method you send is: " + method);// 继续循环读取浏览器客户端发出的一行一行的数据while ((line = reader.readLine()) != null) {if (line.equals("")) {// 当line等于空行的时候标志Header消息结束break;}System.out.println("the Http Header is : " + line);}// 如果是POST的请求,直接打印POST提交上来的数据if ("post".equals(method.toLowerCase())) {System.out.println("the post request body is: " + reader.readLine());} else if ("get".equals(method.toLowerCase())) {// 判断是get类型的http请求处理// 根据http请求的资源后缀名来确定返回数据// 比如下载一个图片文件,我这里直接给定一个图片路径来模拟下载的情况if (resource.endsWith(".jpg")) {transferFileHandle("d://1.jpg", client);closeSocket(client);continue;} else {// 直接返回一个网页数据// 其实就是将html的代码以字节流的形式写到IO中反馈给客户端浏览器。// 浏览器会根据http报文“Content-Type”来知道反馈给浏览器的数据是什么格式的,并进行什么样的处理PrintStream writer = new PrintStream(client.getOutputStream(), true);writer.println("HTTP/1.0 200 OK");// 返回应答消息,并结束应答writer.println("Content-Type:text/html;charset=utf-8");writer.println();// writer.println("Content-Length:" +// html.getBytes().length);// 返回内容字节数writer.println("<html><body>");writer.println("<a href='www.baidu.com'>百度</a>");writer.println("<img src='https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png'></img>");writer.println("</html></body>");// writer.println("HTTP/1.0 404 Not// found");// 返回应答消息,并结束应答writer.println();// 根据 HTTP 协议, 空行将结束头信息
                                    writer.close();closeSocket(client);// 请求资源处理完毕,关闭socket链接continue;}}} catch (Exception e) {System.out.println("HTTP服务器错误:" + e.getLocalizedMessage());}}} catch (Exception e) {e.printStackTrace();}}}private void closeSocket(Socket socket) {try {socket.close();} catch (IOException ex) {ex.printStackTrace();}System.out.println(socket + "离开了HTTP服务器");}private void transferFileHandle(String path, Socket client) {File fileToSend = new File(path);if (fileToSend.exists() && !fileToSend.isDirectory()) {try {// 根据Socket获取输出流对象,将访问的资源数据写入到输出流中PrintStream writer = new PrintStream(client.getOutputStream());writer.println("HTTP/1.0 200 OK");// 返回应答消息,并结束应答writer.println("Content-Type:application/binary");writer.println("Content-Length:" + fileToSend.length());// 返回内容字节数writer.println();// 根据 HTTP 协议, 空行将结束头信息FileInputStream fis = new FileInputStream(fileToSend);byte[] buf = new byte[fis.available()];fis.read(buf);writer.write(buf);writer.close();fis.close();} catch (IOException e) {e.printStackTrace();}}}}
}

抄录网址

  1. 解析Tomcat内部结构和请求过程
  2. Tomcat运行过程和简单模拟

转载于:https://www.cnblogs.com/haimishasha/p/10744696.html

Tomcat系列(6)——Tomcat处理一个HTTP请求的过程相关推荐

  1. tomcat 执行一个web请求的过程

    2019独角兽企业重金招聘Python工程师标准>>> Tomcat Server处理一个http请求的过程 假设来自客户的请求为: http://localhost:8080/ws ...

  2. 死磕Tomcat系列(6)——Tomcat如何做到热加载和热部署的

    死磕Tomcat系列(6)--Tomcat如何做到热加载和热部署的 热部署就是在服务器运行时重新部署项目,热加载即在在运行时重新加载class,从而升级应用. 通常情况下在开发环境中我们使用的是热加载 ...

  3. Tomcat系列(5)——Tomcat配置详细部分

    Tomcat的架构图 Tomcat的组织结构 Tomcat是一个基于组件的服务器,它的构成组件都是可配置的,其中最外层的是Catalina servlet容器,其他组件按照一定的格式要求配置在这个顶层 ...

  4. 浏览器一个HTTP请求的过程

    浏览器一个请求的过程 当我们在浏览器地址栏输入 www.xx.com ,然后回车, 这个请求背后经历了什么?以下是个人理解,如有偏差,请纠正! 首先重新温习下网络模型: 七层结构(至顶向下):应用层. ...

  5. 一文读懂一个URL请求的过程是怎样的

    前言 当我们在浏览器中输入一个URL访问地址,然后浏览器返回给我们一个响应页面,这内部过程到底是怎样的呢?下面我将从以下几个方面阐述一个 WEB请求过程到底是怎样: 浏览器缓存 DNS域名解析 TCP ...

  6. Tomcat目录结构及Tomcat Server处理一个http请求的过程

    http://blog.sina.com.cn/s/blog_62cb15980101jh9x.html 1.Tomcat的结构概述 Tomcat服务器是由一系列可配置的组件构成,其核心组件是Cata ...

  7. Tomcat处理一个HTTP请求的过程

    一.Tomcat的组成 (1)Server 服务器元素代表整个catalina servlet容器.是单例模式. (2)Service Service是这样一个集合:它由一个或者多个Connector ...

  8. 蘑菇君深入源码学习Tomcat系列 (1) - Tomcat与Servlet的那些事

    瞎扯淡 最近很焦虑,每天过着咸鱼般的生活,感觉前途渺茫.再这么下去,整个人就真成咸鱼了.焦虑来源于日复一日工作中,自己变得越来越麻木,不会动脑思考.憋说举一反三了,脑子多转一下都感觉要耗尽全身气力. ...

  9. Tomcat系列:Tomcat版本与JDK版本对应关系

    http://tomcat.apache.org/whichversion.html

最新文章

  1. php获取浏览器cookies,简单实现创建以及读取浏览器中cookie的几种方法
  2. docker安装redis(最新)
  3. NET 2005 中通过TryParse来检验和转换数据类型。
  4. 大数据最核心的关键技术——32个算法,记得收藏!
  5. 系统命名与 SQL 命名之争 - 第 1 部分
  6. win10文件夹加密_(十六)小众但好用:免费开源免注册的同步盘加密工具 Cryptomator...
  7. 全球地区资料json 含中英文 经纬度_2020年Brain Bee北京、天津、河北赛区地区赛参赛说明...
  8. 不用U盘安卓Linux系统,不用U盘,不要光驱,不需分区,windows下安装noilinux双系统...
  9. 想开发微信小游戏,先看看腾讯是如何制定规则的
  10. 【Oracle】sqlplus中 删除键backspace时出现^H
  11. C# 温故而知新:Stream篇(三)
  12. Java知识点汇总以及常见面试题
  13. 7.3通过JVM来监控Spring Boot
  14. puppetmaster 自动签名
  15. Ubuntu下常用软件介绍
  16. Bin文件夹下的DLL可以做什么?
  17. 动态修改esxi虚拟机的CPU和内容
  18. 2017年6月六级翻译明朝
  19. 解决 Java poi 3.8 等版本 操作 word 插入 图片 不成功的问题
  20. 身为程序员还看不懂UML类图? 一文带你零基础学会看UML类图!

热门文章

  1. 开灯关灯java script_Jquery实现视频播放页面的关灯开灯效果
  2. 判断端口是否能用_扫描器篇(八)之python+scapy构造TCP协议包扫描主机端口
  3. linux计划任务案例,Linux计划任务Crontab学习笔记(5):常见错误使用案例
  4. 01 前端HTTP协议(图解HTTP) 之 网络基础
  5. SQL开头quoted和ansiNULL
  6. 正则表达式之量词(重复出现)?、*、+
  7. 一个简单而强大的单片机内存管理器-不带内存碎片整理
  8. IT. IT-hyena成就自我
  9. ~~~~~~~~~~~~~~坏公司鉴别方法 ~~~~~~~~~~~
  10. 蒙层禁止页面滚动的方案