源码下载(Source Code Distributions)地址:https://tomcat.apache.org/download-90.cgi
tomcat 和 servlet 以及 jdk 版本的对应关系:http://tomcat.apache.org/whichversion.html
附上搭建好的环境:https://gitee.com/jhxxb/MyTomcat
一、解压源码
在源码根目录新建 home 文件夹,把 conf 文件夹和 webapps 文件夹移动到 home 文件夹里,然后在源码根目录新建 pom.xml 文件(原来为 Ant 工程,这里把它改为 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> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat</artifactId> <name>tomcat</name> <version>9.0.19</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.10.5</version> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.3</version> </dependency> <!--<dependency>--> <!--<groupId>javax.xml</groupId>--> <!--<artifactId>jaxrpc</artifactId>--> <!--<version>1.1</version>--> <!--</dependency>--> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jaxrpc_1.1_spec</artifactId> <version>2.1</version> </dependency> <!--<dependency>--> <!--<groupId>org.eclipse.jdt.core.compiler</groupId>--> <!--<artifactId>ecj</artifactId>--> <!--<version>4.5</version>--> <!--</dependency>--> <dependency> <groupId>org.eclipse.jdt</groupId> <artifactId>ecj</artifactId> <version>3.17.0</version> </dependency> <dependency> <groupId>org.easymock</groupId> <artifactId>easymock</artifactId> <version>4.0.2</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
二、用 IDEA 直接打开
这里删除了一些无用的文件
1.打开项目属性(F4)
把 java 文件夹标记为 Sources,test 文件夹标记为 Tests
2.运行
找到 org.apache.catalina.startup.Bootstrap 运行 main 方法
2.1、ResponseTrailers 找不到,把 home\webapps\examples\WEB-INF\classes\trailers 目录拷贝到 test 目录下
ResponseTrailers.java
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package trailers; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * This example writes some trailer fields to the HTTP response. */ public class ResponseTrailers extends HttpServlet { private static final long serialVersionUID = 1L; private static final Supplier<Map<String,String>> TRAILER_FIELD_SUPPLIER = new TrailerFieldSupplier(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setTrailerFields(TRAILER_FIELD_SUPPLIER); resp.setContentType("text/plain"); resp.setCharacterEncoding("UTF-8"); PrintWriter pw = resp.getWriter(); pw.print("This response should include trailer fields."); } private static class TrailerFieldSupplier implements Supplier<Map<String,String>> { private static final Map<String,String> trailerFields = new HashMap<>(); static { trailerFields.put("x-trailer-1", "Trailer value one"); trailerFields.put("x-trailer-2", "Trailer value two"); } @Override public Map<String, String> get() { return trailerFields; } } }