├── .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 |
--------------------------------------------------------------------------------