Tomcat源码部署启动问题
- 总结
CookieFilter找不到
问题
- 当maven管理的pom.xml中引入test相关依赖时,启动项目会报CookieFilter找不到问题:
Error:(29, 36) java: 找不到符号
符号: 变量 CookieFilter
位置: 类 util.TestCookieFilter
解决
- 在tomcat/test/utiltest/util包中新建CookieFilter类:
package util;
import java.util.Locale;
import java.util.StringTokenizer;
/**
* Cookie过滤
*
* @author Chova
* @date 2020-09-04
*/
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;
}
}
总结
- 有时候,只需要研究Tomcat源码,并不会进行进行相关代码测试,可以将与test代码测试相关的错误注释掉,也是一个解决问题的办法
- 个人角度不推荐这样做,一个Java攻城狮的自我修养在于应该积极解决错误
Bundle版本错误
问题
- 再次启动Tomcat, 会报Bundle版本错误问题:
Error:osgi: [apache-tomcat-8.5.20-src] Invalid value for Bundle-Version, @VERSION@ does not match [0-9]{1,9}(.[0-9]{1,9}(.[0-9]{1,9}(.[0-9A-Za-z_-]+)?)?)?
解决
- 修改tomcat/modules/jdbc-pool/resource包中的MAINFEST.MF文件
- 将Bundle-Version由 @VERSION@ 修改为8
Manifest-Version: 1.0
Export-Package: org.apache.tomcat.jdbc.naming;uses:="javax.naming,org.ap
ache.juli.logging,javax.naming.spi";version="@VERSION@",org.apache.tomc
at.jdbc.pool;uses:="org.apache.juli.logging,javax.sql,org.apache.tomcat
.jdbc.pool.jmx,javax.management,javax.naming,javax.naming.spi,org.apach
e.tomcat.jdbc.pool.interceptor";version="@VERSION@",org.apache.tomcat.j
dbc.pool.interceptor;uses:="org.apache.tomcat.jdbc.pool,org.apache.juli
.logging,javax.management.openmbean,javax.management";version="@VERSION@
",org.apache.tomcat.jdbc.pool.jmx;uses:="org.apache.tomcat.jdbc.pool,or
g.apache.juli.logging,javax.management";version="@VERSION@"
Bundle-Vendor: Apache Software Foundation
Bundle-Version: 8
Bundle-Name: Apache Tomcat JDBC Connection Pool
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.apache.tomcat.jdbc
Import-Package:
javax.management;version="0",
javax.management.openmbean;version="0",
javax.naming;version="0",
javax.naming.spi;version="0",
javax.sql;version="0",
org.apache.juli.logging;version="0"
启动台日志乱码
问题
- 完成Tomcat相关启动配置后,启动Tomcat项目,发现启动台日志部分乱码
07-Sep-2020 07:41:13.860 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程åºéƒ¨ç½²åˆ°ç›®å½• [/Users/chova/Documents/GitHub/SourceCode/tomcat/home/webapps/host-manager]
原因
- 项目中常见的编码格式有:
- UTF-8 : 变长编码.通常一个汉字会编码成3个字符
- GBK : 定长编码.通常一个汉字编码成2个字符. 全角英文编码是2个字符. 半角英文编码是1个字符
- ISO8859-1 : 定长编码.不支持汉字,通常编码为1个字符
- 根据乱码的样式,分析乱码的原因:
- 上述Tomcat控制台信息乱码的原因在于UTF-8编码,使用ISO解码导致的乱码
解决
- 配置Bootstrap的VM options选项:
-Duser.language=en
-Duser.region=US
-Dfile.encoding=UTF-8
总结
- Tomcat 8的post编码为ISO8859-1, 需要进行字符集设置:
request.setCharacterEncoding("utf-8");
- Tomcat 8之后的URL编码格式为UTF-8, 之前都是ISO8859-1
-
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
- 默认情况下 ,Tomcat使用的编码是ISO8859-1
- 修改Tomcat安装文件夹下的conf/server.xml: 添加URIEncoding属性,将该属性值设置为UTF-8, 让Tomcat以UTF-8的方式处理HTTP请求
访问页面报NPE异常
问题
- 再次启动Tomcat, 启动成功,访问Tomcat服务器:
localhost:8080
- 访问页面报NullPointerException异常:
org.apache.jasper.JasperException: java.lang.NullPointerException
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:598)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:514)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
java.lang.NullPointerException
org.apache.jsp.index_jsp._jspService(index_jsp.java:424)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:71)
javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
原因
- 启动Bootstrap.java时没有加载JasperInitializer, 从而导致无法编译JSP
解决
- 在Tomcat源码中的ContextConfig类中的configStart方法中初始化JSP解析器:
context.addServletContainerInitializer(new JasperInitializer(), null);
ClassNotFoundException无法找到类
问题
- 有时,启动Tomcat会报ClassNotFoundException无法找到类异常:
java.lang.ClassNotFoundException: listeners.ContextListener
解决
- 删除webapps下的examples文件夹
总结
- 在研究源码,部署源码环境的过程中,遇到问题要积极解决,力求保证完全正确,不要逃避出现的异常问题
- 一边解决问题,一边提升自己.详细记录下自己解决问题的过程