springboot 打成war 部署到tomcat下的采坑记录()

springboot 2.1.8

jdk 1.8.0_131

tomcat 8.5.47

maven 3.6.1

 

坑一:(解决方法:重写filter的init和destroy即可),详情见下

09-Jan-2020 11:33:59.295 信息 [Abandoned connection cleanup thread] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
	java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load []. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
		at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1380)
		at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1032)
		at com.mysql.jdbc.AbandonedConnectionCleanupThread.checkContextClassLoaders(AbandonedConnectionCleanupThread.java:90)
		at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:63)
		at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
		at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
		at java.lang.Thread.run(Thread.java:748)

解决方法:

1.查看日志,去tomcat的log下找localhost.xxxx-xx-xx.log,不要看catalina的log

我的错误日志

09-Jan-2020 11:33:54.572 严重 [localhost-startStop-1] org.apache.catalina.core.StandardContext.filterStart 启动过滤器异常
	java.lang.AbstractMethodError
		at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:283)
		at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:112)
		at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4546)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5191)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
		at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:970)
		at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1841)
		at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
		at java.util.concurrent.FutureTask.run(FutureTask.java:266)
		at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
		at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
		at java.lang.Thread.run(Thread.java:748)

由日志可知是filter的问题。

我的filter

package com.xxx.common.filter;


import com.xxx.common.servlet.ApiHttpServletRequestWrapper;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @Decription: 重新封装request
 * @Author: li_yanfei
 * @Date: 2019/11/12 16:23
 * @Version: 1.0
 */
public class XxxFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if(request instanceof HttpServletRequest) {
            requestWrapper = new ApiHttpServletRequestWrapper((HttpServletRequest) request);
        }
        
        if(requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }

}

上面的代码,在idea中运行项目,和将项目打成jar包放到服务器上通过java -jar 运行,没有任何问题。只有在将项目打成war放到tomcat下时才报的上述错误。

修改后的代码

package com.xxx.common.filter;


import com.xxx.common.servlet.ApiHttpServletRequestWrapper;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * @Decription: 重新封装request
 * @Author: li_yanfei
 * @Date: 2019/11/12 16:23
 * @Version: 1.0
 */
public class XxxFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if(request instanceof HttpServletRequest) {
            requestWrapper = new ApiHttpServletRequestWrapper((HttpServletRequest) request);
        }
        
        if(requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}

}

对,只重写了两个接口方法的,init和destroy,而且还是空实现,没做任何改变。

重新打包,部署,启动,问题解决。

不完全分析:

抛出问题:Filter接口中的init和destroy方法都是default的,实现类可以不用重写这两个方法,为何war部署下需要重写呢?

解释(某度搜索到的):

在Java8之前,接口中的实现方法必须是abstract的,实现该接口的类必须重写该方法,接口只负责声明该方法。
Java8给接口增加了default关键词,用default修饰的方法可以有实现内容,实现该接口的类可以不重写用default修饰的方法,类似于继承。但这样也会带来新的问题。
Java中只能继承一个类,但是可以实现多个接口,当多个接口中有同一个方法时,以前是没问题的,因为实现类必须重写方法。但现在,当多个接口中有同一个用default修饰的方法时,就无法判断到底实现的是哪个接口的方法。这种情况下,就必须重写方法。
还有一种情况,一个类继承的父类和实现的接口中都有同一个方法,而这个类又没有重写时,实现的是父类的方法,而不是接口中的方法。

疑问1:按照上述说法,我的filter是单实现,为何还要重写这俩方法?

猜测可能filter在项目启动的时候又经过包装吧,没找到源码佐证。等找到了再回来补

 

疑问2:为何tomcat部署下有问题,jar没问题。

还没有找到原因,有知道的求解惑

 

 

 

你可能感兴趣的:(java,springboot,学习笔记)