Web基础+Tomcat

Web 基础和 tomcat

tomcat 学艺

JavaEE 规范:JDBC,JNDI,EJB,RMI,JSP,Servlets,XML,JMS,Java IDL,JTS,JTA,JavaMail,JAF。
Tomcat 只实现了俩:Servlet 和 JSP。其他服务器比如 JBoss、Weblogic 啥的都是完全支持的。所以人们往往更愿意叫 Tomcat 为轻量级的服务器,也有叫它 Servlet/JSP 容器的。所以 java 开发时不需要额外依赖 servlet 和 JSP,但是需要额外依赖 JDBC,因为 tomcat 里只实现了 Servlet 和 JSP。

服务器

服务器的主要作用:

  • 将资源对外暴露
  • 配合各种传输协议进行响应输出
    请先了解以下三个概念:
  • IP:电子设备在网络中的唯一表示,一个 IP 对应一台实体电脑。
  • 端口:应用程序在计算机中的唯一标识,一个端口只能被唯一程序占用。
  • 传输协议:数据传输的规则。
    浏览器与服务器通信流程如下:

    实际请求时,最终还是要换算成 IP 去访问。总得来说有两种换算的途径:1.本机的 hosts 文件 2.DNS 服务器
    DNS 解析域名得到对应的 IP 后,Request 请求里还是会带上 host。为什么?

因为:域名!=IP。

实际上一个 IP 可以对应多个域名。也就是说一台实体服务器(大铁柜),理论上可以有多个域名(虚拟主机)。实体服务器和网站是两个概念。IP 只是对应实体服务器,而域名对应具体的网站。

比如上面百度服务器,虽然看起来 115.239.210.27 这个 IP 完全等同于http://www.baidu.com,但也有可能这个IP对应的服务器上配置了两个虚拟主机:www.baidu.com和tieba.baidu.com。所以即使找到了IP对应的服务器实体,Request请求还是要带上host主机名,以确定是哪个虚拟主机。

另外,如果两个域名对应同一个 IP,那么必须设置其中一个域名为默认的,不然同一台服务器有两个虚拟主机,我该访问谁?
已经知道 IP,就无需 DNS 解析,可直接访问服务器。若这个 IP 对应的服务器有两个虚拟主机,而用户 Request 请求行中又没有指定 host,则会访问默认主机(因此服务器要事先指定默认主机!Tomcat 默认 localhost,localhost 这个名称是一个保留域名)

最后,再用 Tomcat 举个例子。比如,现在我有一台笔记本电脑(一个实体服务器),它的本机 IP 是 192.168.112.1,我在上面装了 Tomcat。如果 Tomcat 不改动配置,则默认只有一个虚拟主机 localhost(默认主机)。接着我开发了一个 JavaWeb 程序 demo1 部署到 Tomcat,然后我同事在浏览器输入下方地址。192.168.112.1:8080/demo1/index.html。访问我的电脑。虽然没有带 host,但是 localhost 是默认的,于是访问它。

3 个容易混淆的概念

其实,Tomcat 服务器 = Web 服务器 + Servlet/JSP 容器(Web 容器)。
Web 服务器的作用是接收客户端的请求,给客户端作出响应。但是很明显,服务器不止静态资源呀,所以客户端发起请求后,如果是动态资源,Web 服务器不可能直接把它响应回去(比如 JSP),因为浏览器只认识静态资源。所以对于 JavaWeb 程序而言,还需要 JSP/Servlet 容器,JSP/Servlet 容器的基本功能是把动态资源转换成静态资源。我们 JavaWeb 工程师需要使用 Web 服务器和 JSP/Servlet 容器,而通常这两者会集于一身,比如 Tomcat。

我们开发的 Web 应用都是半成品

我们开发 JavaWeb 时,你操心过如何接收 HTTP 请求和响应 HTTP 请求吗?显然没有嘛!因为服务器都已经完成了。所以,我们用 Java 开发的 Web 应用只是一个半成品,类似于一个插件,而服务器则像一个收发器:

什么是动态资源

其实对于何谓动态资源,我也没有很精准的概念。要讲清楚一个东西是什么,有时是比较难的事。不如先说它不是什么。

首先,动态资源不等同于动态页面。所谓动态页面,就是页面会动,而会动的页面不一定是动态资源。比如我可以用 JQuery 执行一段代码,让一个 Div 不断放大缩小,但是很显然它还是一个 HTML 页面。

所谓动态资源,其实最显著的特征就是它能动态地生成 HTML!比如 JSP。动态资源有个“特色”:它的数据是“可拼装”的、而且“可以随时间变化”。下面用号称可以抗住 8 个明星同时出轨的新浪服务器举个例子:

Tomcat 架构

目录

Tomcat 的架构

server.xml 配置



简略解释一下 xml 里的配置:

tomcat 中的 DefaultServlet

实际使用 tomcat 的时候,即使没有编写 Servlet,tomcat 依然可以处理请求返回结果,是因为 tomcat 有一个 DefaultServlet。像 Tomcat 这样的 Servlet 容器来说,任何一个请求的背后肯定有个 Servlet 在默默处理:

在 tomcat/conf/web.xml 中,声明了一个 DefaultServlet。我们每个动态 web 工程都有个 web.xml,而 conf 里的这个,是它们的“老爹”。它里面的配置,如果动态 web 工程没有覆盖,就会被“继承”下来。我们会发现,conf/web.xml 里配置了一个 DefaultServlet:

DefaultServlet 的作用:最低级匹配,当没有对应的 Servlet 处理当前请求时,才轮到它处理。要么找到并响应请求的资源,要么给出 404 页面

JSP 剖析

我们都知道 JSP 是“化了浓妆”的 Servlet,但是好不容易伪装成了一个 JSP,是谁帮它卸妆的呢?另外,大家仔细想想,一般来说 JavaWeb 阶段我们访问资源有三种“形式”:

1
2
3
localhost:8080/demo/AServlet:很明显,我们手动写了一个AServlet处理它
localhost:8080/demo/haha.html:虽然我们没写,但是Tomcat自己准备了DefaultServlet
localhost:8080/demo/index.jsp:我擦,谁来处理?

对呀,细思恐极,这*.jsp 的资源,谁来处理?其实就是 JspServlet。它的作用简而言之就是:

首先,根据请求路径找到 JSP
然后,将它“翻译成”Servlet

JSP 的 Servlet 也定义在 conf/web.xml。

tomcat 处理请求的几种方式

tomcat 处理 http 流程

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