Featured image of post IDEA与Tomcat

IDEA与Tomcat

尝试弄清楚IDEA运行Tomcat时,IDEA做了那些事儿

前情提要

IDEA 中,仅编写了一个.java文件即可部署一个接口,怎么做到的?

笔者使用Test.java源码如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package jndi.example.study;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

@WebServlet("/test")
public class Test extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            // 获取JNDI上下文
            Context ctx = new InitialContext();

            // 查找数据源
            Context envContext = (Context) ctx.lookup("java:/comp/env");
            DataSource ds = (DataSource) envContext.lookup("jdbc/sec");

            // 获取连接
            Connection conn = ds.getConnection();

            System.out.println("[+] success!");

            // 执行查询
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM sec.user;");

            // 处理结果集
            while (rs.next()) {
                System.out.println(rs.getString("email"));
            }

            // 关闭连接
            rs.close();
            stmt.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如何启动发布到Web端的?分为两方面,所以将会有两篇文章

本文聚焦于 IDEA 启动 Tomcat 时做了哪些事儿?

下篇文章聚焦于 Tomcat 源码中如何识别并分配处理类

完整流程

IDEATomcat的联动其实算是开发工具和运行服务的配合,所以时间逻辑来看,应该是先开发,后运行,先IDEA,后Tomcat

  1. 创建项目
  2. IDEA开发web业务代码
  3. IDEA上配置Tomcat
  4. IDEA将工程构建为一个可以发布的app目录/war包/jar包 (项目的依赖包最好放在app/WEB-INF/lib下)
  5. IDEA将构建好的app部署到tomcat中,启动并运行

IDEA启动Tomcat

构建好的项目并不会放在Tomcat安装目录的webapps中

为了防止污染本地安装的Tomcat,放在了Tomcat生成的副本中

image-20241206164924657

这个目录下的东西如下图所示

image-20241206164957231

这些是一些关键的配置文件

这样在调试时,有些映射需要修改配置文件的时候,也不会污染本地安装的Tomcat软件配置

原理总结

IDEA部署并运行项目的原理:

  • idea并没有直接进将编译好的项目放入tomcat的webapps中

  • idea根据关联的tomcat,创建了一个tomcat配置文件的副本,将项目的生成目录内容通过这些配置文件联系起来

  • idea的tomcat配置文件副本在C:\Users\Dan\AppData\Local\JetBrains\IntelliJIdea2024.2\tomcat\

  • idea的tomcat副本不是一个完整的tomcat,副本里只是准备了和当前项目相关的配置文件而已

  • idea启动tomcat时,是让本地tomcat程序按照tomcat副本里的配置文件运行

  • idea的tomcat副本部署项目的模式是通过conf/Catalina/localhost/*.xml配置文件的形式实现项目部署的

    下图是IDEA的conf\Catalina\localhost\jndidemo_war_exploded.xml文件,可以看到与项目输出路径联系起来了 image-20241206165317790

简单理解:IDEA通过复制配置文件,达到不修改源配置文件的方式,自动设置了一系列配置,使其和工程输出文件相关联

但是由于只有配置文件被复制,所以执行文件还是Tomcat安装目录下的,且如果有.jar需要依赖,也需要放到Tomcat安装路径的lib目录下

IDEA联动部署Tomcat进行部署

如何部署?IDEA提供了两种方式,如下图:

image-20241206171955293

  1. war 模式:将WEB工程以包的形式上传到服务器。

这种模式可以称之为是发布模式,打包,即是先将项目打成war包,再进行发布。

  • war 模式下的映射设置如下

conf\Catalina\localhost\jndidemo_war.xml

1
<Context path="/jndidemo_war" docBase="D:\Users\Dan\Code\Java\jndidemo\out\artifacts\jndidemo_war\jndidemo_war.war" />
  1. war exploded 模式:将WEB工程以当前文件夹的位置关系上传到服务器。

这种模式是所有文件夹文件路径不打包的情况下,包括 jsp 页面 、servlet 等等连接到 Tomcat 进行加载部署

因此这种方式支持热部署,一般在开发的时候也是用这种方式。

  • war exploded 模式下的映射设置如下

conf\Catalina\localhost\jndidemo_war_exploded.xml

1
<Context path="/jndidemo_war_exploded" docBase="D:\Users\Dan\Code\Java\jndidemo\out\artifacts\jndidemo_war_exploded" />

Tips

在配置 Tomcat 进行热部署时,设置执行更新时更新资源或手动重启服务器即可,这样更新的服务就能及时地显示出来了。

Ref

https://blog.csdn.net/Helen_1997_1997/article/details/131935349

https://blog.csdn.net/m0_68988603/article/details/124285667

Dan❤Anan
Built with Hugo
主题 StackJimmy 设计