『JavaWeb』Tomcat簡介

本篇博客主要介紹Tomcat的簡單知識。

什麼是Tomcat?


Tomcat本質就是一個軟件。一款運行在用戶態(站在操作系統角度),運行在應用層(站在網絡層次)的軟件。它是用來溝通瀏覽器(用戶)和後臺服務(Servlet對象)之間的橋樑和中介
我們可以稱Tomcat爲HTTPServer、Web容器或者Servlet容器

Tomcat的安裝


Tomcat的安裝非常簡單,下載安裝包解壓即可。安裝包可去官網下載。

目錄結構


apache-tomcat-8.5.47\
	bin/    	存放各種啓動、停止的腳本。*sh是在Linux下用的,*bat是在Windows下用的
	    startup.bat    啓動服務,雙擊即可運行
	conf/   	相關的配置文件
	lib/    	運行Tomcat需要的類庫
	logs/   	運行時的日誌文件,有時需要查看日誌文件來定位問題
	temp/   	臨時文件夾
	webapps/	存放我們要運行的web application的文件夾,最常用的一個文件夾
	work/   	Tomcat內部進行預編譯的文件夾

Tomcat的啓動


雙擊bin/startup.bat啓動
在這裏插入圖片描述
在這裏插入圖片描述
我們可以在瀏覽器輸入http://localhost:8080/訪問的是webapps\ROOT\文件夾下的應用
在這裏插入圖片描述
我們來看一下webapps的目錄結構

webapps\
	docs\
	examples\
	host-manager\
	manager\
	ROOT\

webapps目錄下的每個文件夾都代表一個web應用,可以通過下列URL在瀏覽器中訪問

  • http://localhost:8080/docs/
    在這裏插入圖片描述
  • http://localhost:8080/examples/
    在這裏插入圖片描述
  • http://localhost:8080/host-manager
    在這裏插入圖片描述

Tomcat使用示例


不使用IDEA創建一個web應用


我們在webapps目錄下創建一個新的文件夾hello,並且創建好如下的目錄結構
在這裏插入圖片描述
index.html中的內容如下

<html>
	<head>
		<meta charset="utf-8" />
	</head>
	<body>
		<h1>Hello,World!</h1>
	</body>
</html>

web.xml中的內容如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1"
         metadata-complete="true">
         
    <servlet>
        <servlet-name>Hello</servlet-name>
        <servlet-class>HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/hello-world</url-pattern>
    </servlet-mapping>
</web-app>

HelloServlet.java中的內容如下

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {
	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		response.setContentType("text/html");
		response.setCharacterEncoding("utf-8");
		PrintWriter pw = response.getWriter();
		
		pw.println("<h1>你好,世界!</h1>");
	}
}

下面我們將HelloServlet.java編譯成HelloServlet.class

javac -cp ..\..\..\..\lib\servlet-api.jar -encoding utf-8 HelloServlet.java

在這裏插入圖片描述
最後我們啓動Tomcat,然後在瀏覽器輸入:http://localhost:8080/hello/,這裏默認訪問的是index.html文件
在這裏插入圖片描述
我們在瀏覽器輸入:http://localhost:8080/hello/hello-world,這裏會去調用HelloServlet中的doGet方法
在這裏插入圖片描述

使用IDEA創建一個web應用


首先我們創建一個maven項目。然後將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>

    <!-- 打war包 -->
    <packaging>war</packaging>

    <groupId>com.sss</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <encoding>UTF-8</encoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <!-- servlet 版本和 tomcat 版本有對應關係,切記 -->
            <version>3.1.0</version>
            <!-- 這個意思是我們只在開發階段需要這個依賴,部署到 tomcat 上時就不需要了 -->
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <!-- 指定最終包的名稱 -->
        <finalName>hello</finalName>

        <!-- 明確指定一些插件的版本,以免受到 maven 版本的影響 -->
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <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>

當前目錄結構如下
在這裏插入圖片描述
我們需要在src/main目錄下添加如下目錄結構
在這裏插入圖片描述
其中HelloServlet.java、index.html、web.xml中的內容和前面一致
我們也可以將web.xml中的以下內容去掉,改用@WebServlet("/hello-world")註解的方式也是一樣的。
在這裏插入圖片描述
@WebServlet("/hello-world")註解的使用方式如下
在這裏插入圖片描述
然後,我們使用maven的package命令進行打包
在這裏插入圖片描述
我們將該war包拷貝到webapps目錄下,啓動Tomcat即可
我們在瀏覽器輸入:http://localhost:8080/hello/,這裏默認訪問的是index.html文件
在這裏插入圖片描述
我們在瀏覽器輸入:http://localhost:8080/hello/hello-world,這裏會去調用HelloServlet中的doGet方法
在這裏插入圖片描述

Tomcat相關概念


HttpServlet和Servlet的關係


Servlet是Java中的一個接口

interface Servlet {
	void init(ServletConfig var1) throws ServletException;
	void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
	void destroy();
}

HttpServlet是Servlet接口的一個實現類,但它本身是個抽象類。所以當我們繼承HttpServlet,需要實現我們要支持的方法,如doGet、doPost等。

abstract class HttpServlet implements Servlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 根據request的method不同,調用不同的方法
	}

	// GET時調用
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// ...
	}

	// POST時調用
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// ...
	}

	// 其他HTTP協議支持的方法
}

Tomcat的基本原理


一個Tomcat實例可以有多個host,一個host可以有多個Context,一個Context中可以由多個Servlet對象
每個host都有一組Context,webapps這個目錄下的每個文件夾都是一個Context

一個HTTP請求從到達Tomcat開始,怎麼一步一步被分給我們寫好的一個具體的Servlet對象或者靜態文件

  • 首先,Tomcat根據HTTP請求中的URL中的域名,選擇將該請求交付給具體哪個host
  • 然後,Tomcat跟HTTP請求中的URL中的Context Path,選擇將該請求交付給具體的哪個Context,如果Context Path是/,則交付給ROOT這個比較特別的Context;
  • 最後,Tomcat根據HTTP請求中的URL中去掉Context Path部分的路徑信息結合(web.xml和@WebServlet註解)和靜態文件的目錄結構,找到具體的Servlet對象或者靜態文件
  • 根據不同的HTTP請求方法,調用doGet或者doPost等方法

如果項目中遇到了404,應該查哪些問題?

  • 首先檢查你訪問的是你期望的Tomcat嗎,URL中的端口是否是Tomcat正在監聽的端口
  • 然後檢查訪問的URL是哪個host,是否存在
  • 根據URL中的Context Path,看下訪問的是哪個Context,是否存在
  • 根據URL中的剩餘路徑部分,結合web.xml和@WebServlet註解還有類文件,靜態文件,看看配置是否正確
  • 最後再看一下404是不是你的Servlet代碼中加的

Servlet對象的生命週期?

  • 每個Servlet對象,在其生命過程中,init()在啓動時被調用一次,destroy()在退出時被調用一次,service()在每次請求的處理中都會被調用一次

Servlet對象工作多線程環境下

  • 因爲Tomcat內部是使用線程處理每個請求的,並且每個Servlet對象只會存在一個,所以我們覆寫的doGet等方法,是在多線程環境下運行的,需要考慮線程安全問題。

總結


  • Tomcat就是一個Web Container,內部實現了一個HTTP服務器;
  • 同時會根據不同的URL,區分出是靜態內容還是動態內容
  • 如果是動態內容,則根據web.xml中的配置找到對應的Servlet對象進行處理
  • 我們自己寫的代碼只是這個環節中的一個步驟,不再需要從main入口開始實現了;
  • 我們在Servlet中寫的代碼,其實都是一個在多線程環境下運行的,要注意線程安全問題
  • 每個Servlet對象,在其生命過程中,init()在啓動時被調用一次,destroy()在退出時被調用一次,service()在每次請求的處理中都會被調用一次
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章