├── .gitignore ├── README.md ├── pom.xml └── src └── main ├── java └── com │ └── zero │ ├── launch │ └── Main.java │ └── servlet │ └── HelloServlet.java └── webapp └── index.jsp /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /target/ 3 | *.iml 4 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tomcat 2 | 内嵌 Tomcat 源码阅读。 3 | ## 创建 pom.xml 4 | 5 | ```xml 6 | 8 | 4.0.0 9 | com.zero.sample 10 | tomcat-embedded 11 | 1.0-SNAPSHOT 12 | jar 13 | embeddedTomcatSample Maven Webapp 14 | http://maven.apache.org 15 | 16 | 8.5.38 17 | 18 | 19 | 20 | org.apache.tomcat.embed 21 | tomcat-embed-core 22 | ${tomcat.version} 23 | 24 | 25 | org.apache.tomcat.embed 26 | tomcat-embed-jasper 27 | ${tomcat.version} 28 | 29 | 30 | org.apache.tomcat 31 | tomcat-jasper 32 | ${tomcat.version} 33 | 34 | 35 | org.apache.tomcat 36 | tomcat-jasper-el 37 | ${tomcat.version} 38 | 39 | 40 | org.apache.tomcat 41 | tomcat-jsp-api 42 | ${tomcat.version} 43 | 44 | 45 | 46 | embeddedTomcatSample 47 | 48 | 49 | org.codehaus.mojo 50 | appassembler-maven-plugin 51 | 2.0.0 52 | 53 | target 54 | 55 | 56 | com.zero.launch.Main 57 | webapp 58 | 59 | 60 | 61 | 62 | 63 | package 64 | 65 | assemble 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | ``` 74 | 75 | ## 添加一个启动类 76 | ```java 77 | package com.zero.launch; 78 | 79 | import org.apache.catalina.WebResourceRoot; 80 | import org.apache.catalina.WebResourceSet; 81 | import org.apache.catalina.core.StandardContext; 82 | import org.apache.catalina.startup.Tomcat; 83 | import org.apache.catalina.webresources.DirResourceSet; 84 | import org.apache.catalina.webresources.EmptyResourceSet; 85 | import org.apache.catalina.webresources.StandardRoot; 86 | 87 | import java.io.File; 88 | import java.net.URISyntaxException; 89 | import java.nio.file.Files; 90 | import java.nio.file.Path; 91 | 92 | public class Main { 93 | 94 | private static File getRootFolder() { 95 | try { 96 | File root; 97 | String runningJarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath().replaceAll("\\\\", 98 | "/"); 99 | int lastIndexOf = runningJarPath.lastIndexOf("/target/"); 100 | if (lastIndexOf < 0) { 101 | root = new File(""); 102 | } else { 103 | root = new File(runningJarPath.substring(0, lastIndexOf)); 104 | } 105 | System.out.println("application resolved root folder: " + root.getAbsolutePath()); 106 | return root; 107 | } catch (URISyntaxException ex) { 108 | throw new RuntimeException(ex); 109 | } 110 | } 111 | 112 | public static void main(String[] args) throws Exception { 113 | 114 | File root = getRootFolder(); 115 | System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true"); 116 | Tomcat tomcat = new Tomcat(); 117 | Path tempPath = Files.createTempDirectory("tomcat-base-dir"); 118 | tomcat.setBaseDir(tempPath.toString()); 119 | 120 | //The port that we should run on can be set into an environment variable 121 | //Look for that variable and default to 8080 if it isn't there. 122 | String webPort = System.getenv("PORT"); 123 | if (webPort == null || webPort.isEmpty()) { 124 | webPort = "8080"; 125 | } 126 | 127 | tomcat.setPort(Integer.parseInt(webPort)); 128 | File webContentFolder = new File(root.getAbsolutePath(), "src/main/webapp/"); 129 | if (!webContentFolder.exists()) { 130 | webContentFolder = Files.createTempDirectory("default-doc-base").toFile(); 131 | } 132 | StandardContext ctx = (StandardContext) tomcat.addWebapp("", webContentFolder.getAbsolutePath()); 133 | //Set execution independent of current thread context classloader (compatibility with exec:java mojo) 134 | ctx.setParentClassLoader(Main.class.getClassLoader()); 135 | 136 | System.out.println("configuring app with basedir: " + webContentFolder.getAbsolutePath()); 137 | 138 | // Declare an alternative location for your "WEB-INF/classes" dir 139 | // Servlet 3.0 annotation will work 140 | File additionWebInfClassesFolder = new File(root.getAbsolutePath(), "target/classes"); 141 | WebResourceRoot resources = new StandardRoot(ctx); 142 | 143 | WebResourceSet resourceSet; 144 | if (additionWebInfClassesFolder.exists()) { 145 | resourceSet = new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClassesFolder.getAbsolutePath(), "/"); 146 | System.out.println("loading WEB-INF resources from as '" + additionWebInfClassesFolder.getAbsolutePath() + "'"); 147 | } else { 148 | resourceSet = new EmptyResourceSet(resources); 149 | } 150 | resources.addPreResources(resourceSet); 151 | ctx.setResources(resources); 152 | 153 | tomcat.start(); 154 | tomcat.getServer().await(); 155 | } 156 | } 157 | ``` 158 | ## 创建一个 Servlet 159 | 在 com.zero.servlet 下创建 Servlet 160 | 161 | ```java 162 | package com.zero.servlet; 163 | 164 | import javax.servlet.ServletException; 165 | import javax.servlet.ServletOutputStream; 166 | import javax.servlet.annotation.WebServlet; 167 | import javax.servlet.http.HttpServlet; 168 | import javax.servlet.http.HttpServletRequest; 169 | import javax.servlet.http.HttpServletResponse; 170 | import java.io.IOException; 171 | 172 | @WebServlet( 173 | name = "HelloServlet", 174 | urlPatterns = {"/hello"} 175 | ) 176 | public class HelloServlet extends HttpServlet { 177 | 178 | @Override 179 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) 180 | throws ServletException, IOException { 181 | ServletOutputStream out = resp.getOutputStream(); 182 | out.write("hello heroku".getBytes()); 183 | out.flush(); 184 | out.close(); 185 | } 186 | 187 | } 188 | ``` 189 | ## 添加一个 JSP 主页 190 | 在 src/main/webapp 目录 创建一个index.jsp 191 | ``` 192 | 193 | 194 |

Hello MageByte!

195 | 196 | 197 | ``` 198 | ## 运行程序 199 | To generate the start scripts simply run: 200 | 201 | $ mvn package 202 | And then simply run the script. On Mac and Linux, the command is: 203 | 204 | $ sh target/bin/webapp 205 | On Windows the command is: 206 | 207 | C:/> target/bin/webapp.bat 208 | 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 209 | 210 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.zero.sample 5 | tomcat-embedded 6 | 1.0-SNAPSHOT 7 | jar 8 | embeddedTomcatSample Maven Webapp 9 | http://maven.apache.org 10 | 11 | 8.5.51 12 | 13 | 14 | 15 | org.apache.tomcat.embed 16 | tomcat-embed-core 17 | ${tomcat.version} 18 | 19 | 20 | org.apache.tomcat.embed 21 | tomcat-embed-jasper 22 | ${tomcat.version} 23 | 24 | 25 | org.apache.tomcat 26 | tomcat-jasper 27 | ${tomcat.version} 28 | 29 | 30 | org.apache.tomcat 31 | tomcat-jasper-el 32 | ${tomcat.version} 33 | 34 | 35 | org.apache.tomcat 36 | tomcat-jsp-api 37 | ${tomcat.version} 38 | 39 | 40 | 41 | embeddedTomcatSample 42 | 43 | 44 | org.codehaus.mojo 45 | appassembler-maven-plugin 46 | 2.0.0 47 | 48 | target 49 | 50 | 51 | com.zero.launch.Main 52 | webapp 53 | 54 | 55 | 56 | 57 | 58 | package 59 | 60 | assemble 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/main/java/com/zero/launch/Main.java: -------------------------------------------------------------------------------- 1 | package com.zero.launch; 2 | 3 | import org.apache.catalina.WebResourceRoot; 4 | import org.apache.catalina.WebResourceSet; 5 | import org.apache.catalina.core.StandardContext; 6 | import org.apache.catalina.startup.Tomcat; 7 | import org.apache.catalina.webresources.DirResourceSet; 8 | import org.apache.catalina.webresources.EmptyResourceSet; 9 | import org.apache.catalina.webresources.StandardRoot; 10 | 11 | import java.io.File; 12 | import java.net.URISyntaxException; 13 | import java.nio.file.Files; 14 | import java.nio.file.Path; 15 | 16 | public class Main { 17 | 18 | private static File getRootFolder() { 19 | try { 20 | File root; 21 | String runningJarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath().replaceAll("\\\\", 22 | "/"); 23 | int lastIndexOf = runningJarPath.lastIndexOf("/target/"); 24 | if (lastIndexOf < 0) { 25 | root = new File(""); 26 | } else { 27 | root = new File(runningJarPath.substring(0, lastIndexOf)); 28 | } 29 | System.out.println("application resolved root folder: " + root.getAbsolutePath()); 30 | return root; 31 | } catch (URISyntaxException ex) { 32 | throw new RuntimeException(ex); 33 | } 34 | } 35 | 36 | public static void main(String[] args) throws Exception { 37 | 38 | File root = getRootFolder(); 39 | System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true"); 40 | Tomcat tomcat = new Tomcat(); 41 | Path tempPath = Files.createTempDirectory("tomcat-base-dir"); 42 | tomcat.setBaseDir(tempPath.toString()); 43 | 44 | //The port that we should run on can be set into an environment variable 45 | //Look for that variable and default to 8080 if it isn't there. 46 | String webPort = System.getenv("PORT"); 47 | if (webPort == null || webPort.isEmpty()) { 48 | webPort = "8080"; 49 | } 50 | 51 | tomcat.setPort(Integer.parseInt(webPort)); 52 | File webContentFolder = new File(root.getAbsolutePath(), "src/main/webapp/"); 53 | if (!webContentFolder.exists()) { 54 | webContentFolder = Files.createTempDirectory("default-doc-base").toFile(); 55 | } 56 | StandardContext ctx = (StandardContext) tomcat.addWebapp("", webContentFolder.getAbsolutePath()); 57 | //Set execution independent of current thread context classloader (compatibility with exec:java mojo) 58 | ctx.setParentClassLoader(Main.class.getClassLoader()); 59 | 60 | System.out.println("configuring app with basedir: " + webContentFolder.getAbsolutePath()); 61 | 62 | // Declare an alternative location for your "WEB-INF/classes" dir 63 | // Servlet 3.0 annotation will work 64 | File additionWebInfClassesFolder = new File(root.getAbsolutePath(), "target/classes"); 65 | WebResourceRoot resources = new StandardRoot(ctx); 66 | 67 | WebResourceSet resourceSet; 68 | if (additionWebInfClassesFolder.exists()) { 69 | resourceSet = new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClassesFolder.getAbsolutePath(), "/"); 70 | System.out.println("loading WEB-INF resources from as '" + additionWebInfClassesFolder.getAbsolutePath() + "'"); 71 | } else { 72 | resourceSet = new EmptyResourceSet(resources); 73 | } 74 | resources.addPreResources(resourceSet); 75 | ctx.setResources(resources); 76 | 77 | tomcat.start(); 78 | tomcat.getServer().await(); 79 | } 80 | } -------------------------------------------------------------------------------- /src/main/java/com/zero/servlet/HelloServlet.java: -------------------------------------------------------------------------------- 1 | package com.zero.servlet; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.ServletOutputStream; 5 | import javax.servlet.annotation.WebServlet; 6 | import javax.servlet.http.HttpServlet; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.io.IOException; 10 | 11 | @WebServlet( 12 | name = "HelloServlet", 13 | urlPatterns = {"/hello"} 14 | ) 15 | public class HelloServlet extends HttpServlet { 16 | 17 | @Override 18 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) 19 | throws ServletException, IOException { 20 | ServletOutputStream out = resp.getOutputStream(); 21 | out.write("hello MageByte".getBytes()); 22 | out.flush(); 23 | out.close(); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello MageByte!

4 | 5 | --------------------------------------------------------------------------------