内嵌 Tomcat 源码阅读。
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zero.sample</groupId>
<artifactId>tomcat-embedded</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>embeddedTomcatSample Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<tomcat.version>8.5.38</tomcat.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>${tomcat.version}</version>
</dependency>
</dependencies>
<build>
<finalName>embeddedTomcatSample</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.0.0</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>com.zero.launch.Main</mainClass>
<name>webapp</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>package com.zero.launch;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.WebResourceSet;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.EmptyResourceSet;
import org.apache.catalina.webresources.StandardRoot;
import java.io.File;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
private static File getRootFolder() {
try {
File root;
String runningJarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath().replaceAll("\\\\",
"/");
int lastIndexOf = runningJarPath.lastIndexOf("/target/");
if (lastIndexOf < 0) {
root = new File("");
} else {
root = new File(runningJarPath.substring(0, lastIndexOf));
}
System.out.println("application resolved root folder: " + root.getAbsolutePath());
return root;
} catch (URISyntaxException ex) {
throw new RuntimeException(ex);
}
}
public static void main(String[] args) throws Exception {
File root = getRootFolder();
System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
Tomcat tomcat = new Tomcat();
Path tempPath = Files.createTempDirectory("tomcat-base-dir");
tomcat.setBaseDir(tempPath.toString());
//The port that we should run on can be set into an environment variable
//Look for that variable and default to 8080 if it isn't there.
String webPort = System.getenv("PORT");
if (webPort == null || webPort.isEmpty()) {
webPort = "8080";
}
tomcat.setPort(Integer.parseInt(webPort));
File webContentFolder = new File(root.getAbsolutePath(), "src/main/webapp/");
if (!webContentFolder.exists()) {
webContentFolder = Files.createTempDirectory("default-doc-base").toFile();
}
StandardContext ctx = (StandardContext) tomcat.addWebapp("", webContentFolder.getAbsolutePath());
//Set execution independent of current thread context classloader (compatibility with exec:java mojo)
ctx.setParentClassLoader(Main.class.getClassLoader());
System.out.println("configuring app with basedir: " + webContentFolder.getAbsolutePath());
// Declare an alternative location for your "WEB-INF/classes" dir
// Servlet 3.0 annotation will work
File additionWebInfClassesFolder = new File(root.getAbsolutePath(), "target/classes");
WebResourceRoot resources = new StandardRoot(ctx);
WebResourceSet resourceSet;
if (additionWebInfClassesFolder.exists()) {
resourceSet = new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClassesFolder.getAbsolutePath(), "/");
System.out.println("loading WEB-INF resources from as '" + additionWebInfClassesFolder.getAbsolutePath() + "'");
} else {
resourceSet = new EmptyResourceSet(resources);
}
resources.addPreResources(resourceSet);
ctx.setResources(resources);
tomcat.start();
tomcat.getServer().await();
}
}在 com.zero.servlet 下创建 Servlet
package com.zero.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(
name = "HelloServlet",
urlPatterns = {"/hello"}
)
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletOutputStream out = resp.getOutputStream();
out.write("hello heroku".getBytes());
out.flush();
out.close();
}
}在 src/main/webapp 目录 创建一个index.jsp
<html>
<body>
<h2>Hello MageByte!</h2>
</body>
</html>
To generate the start scripts simply run:
$ mvn package And then simply run the script. On Mac and Linux, the command is:
$ sh target/bin/webapp On Windows the command is:
C:/> target/bin/webapp.bat That’s it. Your application should start up on port 8080. You can see the JSP at http://localhost:8080 and the servlet and http://localhost:8080/hello