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源码部署启动问题_Tomcat
  • 上述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文件夹
总结
  • 在研究源码,部署源码环境的过程中,遇到问题要积极解决,力求保证完全正确,不要逃避出现的异常问题
  • 一边解决问题,一边提升自己.详细记录下自己解决问题的过程