1. 程式人生 > 資訊 >積極推進科技行業反壟斷,美國 FTC 新主席任命多名高階官員

積極推進科技行業反壟斷,美國 FTC 新主席任命多名高階官員

在上一節中,我們看到,一個完整的Web應用程式的開發流程如下:

  1. 編寫Servlet;
  2. 打包為war檔案;
  3. 複製到Tomcat的webapps目錄下;
  4. 啟動Tomcat。

這個過程是不是很繁瑣?如果我們想在IDE中斷點除錯,還需要開啟Tomcat的遠端除錯埠並且連線上去。

許多初學者經常卡在如何在IDE中啟動Tomcat並載入webapp,更不要說斷點除錯了。

我們需要一種簡單可靠,能直接在IDE中啟動並除錯webapp的方法。

因為Tomcat實際上也是一個Java程式,我們看看Tomcat的啟動流程:

  1. 啟動JVM並執行Tomcat的main()方法;
  2. 載入war並初始化Servlet;
  3. 正常服務。

啟動Tomcat無非就是設定好classpath並執行Tomcat某個jar包的main()方法,我們完全可以把Tomcat的jar包全部引入進來,然後自己編寫一個main()方法,先啟動Tomcat,然後讓它載入我們的webapp就行。

我們新建一個web-servlet-embedded工程,編寫pom.xml如下:

<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.itranswarp.learnjava</groupId>
    <artifactId>web-servlet-embedded</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <java.version>11</java.version>
        <tomcat.version>9.0.26</tomcat.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>${tomcat.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

其中,<packaging>型別仍然為war,引入依賴tomcat-embed-coretomcat-embed-jasper,引入的Tomcat版本<tomcat.version>9.0.26

不必引入Servlet API,因為引入Tomcat依賴後自動引入了Servlet API。因此,我們可以正常編寫Servlet如下:

@WebServlet(urlPatterns = "/")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        String name = req.getParameter("name");
        if (name == null) {
            name = "world";
        }
        PrintWriter pw = resp.getWriter();
        pw.write("<h1>Hello, " + name + "!</h1>");
        pw.flush();
    }
}

然後,我們編寫一個main()方法,啟動Tomcat伺服器:

public class Main {
    public static void main(String[] args) throws Exception {
        // 啟動Tomcat:
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(Integer.getInteger("port", 8080));
        tomcat.getConnector();
        // 建立webapp:
        Context ctx = tomcat.addWebapp("", new File("src/main/webapp").getAbsolutePath());
        WebResourceRoot resources = new StandardRoot(ctx);
        resources.addPreResources(
                new DirResourceSet(resources, "/WEB-INF/classes", new File("target/classes").getAbsolutePath(), "/"));
        ctx.setResources(resources);
        tomcat.start();
        tomcat.getServer().await();
    }
}

這樣,我們直接執行main()方法,即可啟動嵌入式Tomcat伺服器,然後,通過預設的tomcat.addWebapp("", new File("src/main/webapp"),Tomcat會自動載入當前工程作為根webapp,可直接在瀏覽器訪問http://localhost:8080/

通過main()方法啟動Tomcat伺服器並載入我們自己的webapp有如下好處:

  1. 啟動簡單,無需下載Tomcat或安裝任何IDE外掛;
  2. 除錯方便,可在IDE中使用斷點除錯;
  3. 使用Maven建立war包後,也可以正常部署到獨立的Tomcat伺服器中。

對SpringBoot有所瞭解的童鞋可能知道,SpringBoot也支援在main()方法中一行程式碼直接啟動Tomcat,並且還能方便地更換成Jetty等其他伺服器。它的啟動方式和我們介紹的是基本一樣的,後續涉及到SpringBoot的部分我們還會詳細講解。

練習

下載練習:使用嵌入式Tomcat執行Servlet(推薦使用IDE練習外掛快速下載)

注意:引入的Tomcat的scope為provided,在Idea下執行時,需要設定Run/Debug Configurations,選擇Application - Main,鉤上Include dependencies with "Provided" scope,這樣才能讓Idea在執行時把Tomcat相關依賴包自動新增到classpath中。

小結

開發Servlet時,推薦使用main()方法啟動嵌入式Tomcat伺服器並載入當前工程的webapp,便於開發除錯,且不影響打包部署,能極大地提升開發效率。