最近师傅要搞清楚tomcat的启动方式,里面放什么文件,于是打开了相应的资料开始学习。
tomcat源码构建
-
https://gitee.com/archguide/tomcat
从这上面拉代码能节省不少时间。注意要把源码分支调到7.0
之后在命令行执行:ant ide-eclipse下载必要的jar包,通过project structure导入jar包。
- 配置tomcat启动项:
同时会发现缺少一个类,代码如下,直接拷贝到test/util文件夹下面。
package util;
import java.util.Locale;
import java.util.StringTokenizer;
public class CookieFilter {
private static final String OBFUSCATED = "[obfuscated]";
private CookieFilter() {
// Hide default constructor
}
public static String filter(String cookieHeader, String sessionId) {
StringBuilder sb = new StringBuilder(cookieHeader.length());
// Cookie name value pairs are ';' separated.
// Session IDs don't use ; in the value so don't worry about quoted
// values that contain ;
StringTokenizer st = new StringTokenizer(cookieHeader, ";");
boolean first = true;
while (st.hasMoreTokens()) {
if (first) {
first = false;
} else {
sb.append(';');
}
sb.append(filterNameValuePair(st.nextToken(), sessionId));
}
return sb.toString();
}
private static String filterNameValuePair(String input, String sessionId) {
int i = input.indexOf('=');
if (i == -1) {
return input;
}
String name = input.substring(0, i);
String value = input.substring(i + 1, input.length());
return name + "=" + filter(name, value, sessionId);
}
public static String filter(String cookieName, String cookieValue, String sessionId) {
if (cookieName.toLowerCase(Locale.ENGLISH).contains("jsessionid") &&
(sessionId == null || !cookieValue.contains(sessionId))) {
cookieValue = OBFUSCATED;
}
return cookieValue;
}
}
- 之后就可以把自己写的Servlet小项目打成war包
就可以把war包直接放到tomcat的webapps目录下运行啦!(此处注意运行的时候是自动解压的,也就是之后可以删除war,但丝毫不影响运行,)
为什么要有war包
- 从解压过的war包classes目录来看,和jar包中的class并没有任何区别。
那么为什么不能直接用jar包得了? - 仔细观察,webapps下的每个文件夹都被tomcat认为是一个项目,如果是jar包的话,那么tomcat就不知道这是一个项目还是其他项目依赖的jar包了。
tomcat中的容器是什么
在server.xml的配置文件中定义了`<Context path="/HelloLuban" relaodable="false" docBase="/Users/renyong/IdeaProjects/HelloServlet/target/HelloServlet"/>
Context表示了一个应用,也可以叫一个容器。
Context是放到Host下面的,Host可以说是虚拟主机
- 可以这样理解:Host存储了Context,Context存储了Servlet。Host虚拟主机的主要作用就是把我们的应用进行隔离。
隔离的作用有很多,比如说在server.xml中的
就可以针对不同的Host来写日志。
Engine在server.xml中是用来管理Host的
- Wrapper就比较难找了,在server.xml中并没有看到Wrapper标签,其实Wrapper是在Context之下的。当一个Servlet只继承HttpServlet的时候,所有的请求都只对应一个Servlet实例。当该Servlet实现了SingleThreadModel接口的时候,那么每个请求都会对应一个Servlet实例。(后面再讲)
那么同一个Servlet可能会有多个实例。Wrapper就是用来管理多个同类型的实例的。
这样看就比较清晰了