exception starting filter java.lang.AbstractMethodError

编写过滤器时我查看了接口的源码,发现init和destroy方法是default默认方法,因此没有实现这两个方法。以下是Filter接口源码的内容:

package javax.servlet;

import java.io.IOException;


public interface Filter {


    default public void init(FilterConfig filterConfig) throws ServletException {}

    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException;

    default public void destroy() {}
}

下面是我的过滤器的实现:

立马就报错了

如果我实现了这两个方法就不会报错。。。

原因:

我使用的maven构建的web项目,avax.servlet-api-4.0.1.jar包也是maven提供的,因此会和tomcat中的包版本不同。而maven包中就是定义了init和destroy两个default方法,但是tomcat中的包中定义的却是抽象方法,因此必须实现。

由于我没有tomcat中相应包的源码,因此下面通过反汇编来证明,注意,反汇编后定义会和实际定义稍有不同。

首先我们看看maven提供的Filter接口的反汇编结果:

PS D:\a> javap Filter.class
Compiled from "Filter.java"
public interface javax.servlet.Filter {
  public void init(javax.servlet.FilterConfig) throws javax.servlet.ServletException;
  public abstract void doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) throws java.io.IOException, javax.servlet.ServletException;
  public void destroy();
}

可以看到,init和destroy不是抽象方法,都有实现。

在看看tomcat中Filter接口反汇编的结果:

PS D:\> javap Filter.class
Compiled from "Filter.java"
public interface javax.servlet.Filter {
  public abstract void init(javax.servlet.FilterConfig) throws javax.servlet.ServletException;
  public abstract void doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) throws java.io.IOException, javax.servlet.ServletException;
  public abstract void destroy();
}

所有方法都是抽象方法,因此需要实现。

猜你喜欢

转载自blog.csdn.net/jdbdh/article/details/82670343