Tomcat源码解析(一)

羽化登峰 / 2024-03-21 / 原文

一、Apache Tomcat源码环境构建

官网:https://tomcat.apache.org/

二、Maven环境搭建

1、打开IEDA导入项目,然后在项目中创建一个新的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>

  <groupId>org.apache.tomcat</groupId>
  <artifactId>apache-tomcat</artifactId>
  <version>8.5.99</version>
  <build>
    <finalName>apache-tomcat</finalName>
    <sourceDirectory>java</sourceDirectory>
    <resources>
      <resource>
        <directory>java</directory>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

2、然后设置项目为Maven项目,选中pom.xml文件,鼠标右点。选择 Add as Maven Project .

3.导入项目需要的依赖jar包
依赖包下载链接:https://download.csdn.net/download/m0_37928279/89005924

 三、项目启动异常项

1.输出日志中文乱码

1.修改org.apache.jasper.compiler.Localizer#getMessage(java.lang.String)方法,添加标红部分。

  public static String getMessage(String errCode) {
        String errMsg = errCode;
        try {
            if (bundle != null) {
                errMsg = bundle.getString(errCode);
            }
        } catch (MissingResourceException e) {
        }
        try{
            errMsg = new String(errMsg.getBytes("ISO-8859-1"),"UTF-8");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return errMsg;
    }
2.修改org.apache.tomcat.util.res.StringManager#getString(java.lang.String),添加标红部分

public String getString(String key) {
        if (key == null) {
            String msg = "key may not have a null value";
            throw new IllegalArgumentException(msg);
        }

        String str = null;

        try {
            // Avoid NPE if bundle is null and treat it like an MRE
            if (bundle != null) {
                str = bundle.getString(key);
                str = new String(str.getBytes("ISO-8859-1"),"UTF-8");
            }
        } catch (MissingResourceException mre) {
            // bad: shouldn't mask an exception the following way:
            // str = "[cannot find message associated with key '" + key +
            // "' due to " + mre + "]";
            // because it hides the fact that the String was missing
            // from the calling code.
            // good: could just throw the exception (or wrap it in another)
            // but that would probably cause much havoc on existing
            // code.
            // better: consistent with container pattern to
            // simply return null. Calling code can then do
            // a null check.
            str = null;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return str;
    }

2.不支持JSP问题

 1 修改org.apache.catalina.startup.ContextConfig类中的configureStart方法,添加第17行代码。
 2 
 3 protected synchronized void configureStart() {
 4         // Called from StandardContext.start()
 5 
 6         if (log.isTraceEnabled()) {
 7             log.trace(sm.getString("contextConfig.start"));
 8         }
 9 
10         if (log.isTraceEnabled()) {
11             log.trace(sm.getString("contextConfig.xmlSettings", context.getName(),
12                     Boolean.valueOf(context.getXmlValidation()), Boolean.valueOf(context.getXmlNamespaceAware())));
13         }
14 
15         webConfig();
16         //添加JSP解析器
17         context.addServletContainerInitializer(new JasperInitializer(),null);
18         if (!context.getIgnoreAnnotations()) {
19             applicationAnnotationsConfig();
20         }
21         if (ok) {
22             validateSecurityRoles();
23         }
24 
25         // Configure an authenticator if we need one
26         if (ok) {
27             authenticatorConfig();
28         }
29 
30         // Dump the contents of this pipeline if requested
31         if (log.isTraceEnabled()) {
32             log.trace("Pipeline Configuration:");
33             Pipeline pipeline = context.getPipeline();
34             Valve valves[] = null;
35             if (pipeline != null) {
36                 valves = pipeline.getValves();
37             }
38             if (valves != null) {
39                 for (Valve valve : valves) {
40                     log.trace("  " + valve.getClass().getName());
41                 }
42             }
43             log.trace("======================");
44         }
45 
46         // Make our application available if no problems were encountered
47         if (ok) {
48             context.setConfigured(true);
49         } else {
50             log.error(sm.getString("contextConfig.unavailable"));
51             context.setConfigured(false);
52         }
53 
54     }

 3.删除target目录,重启服务