pom.xml不添加servlet-api依赖,那么项目直接就会报错,因为你创建的是一个servlet的子类,编译也无法通过,会报找不到类错误,英文我就不说了。但pom.xml中引入这个依赖,tomcat容器启动没问题,但你访问的时候就出现了上面的错误。这就是jar包冲突了,那么怎么冲突的呢?首先,我们在pom.xml中引入了servlet-api这个依赖,但是我们使用了tomcat7插件,我们看一下tomcat7插件依赖哪些。根据tomcat7插件的坐标,我们找到在仓库中的位置,看到有个文件,
OK,我们打开这个文件,会发现,它依赖了
,我们继续找,然后发现这个tomcat-servlet-api和我们自己在pom.xml引入的servlet-api有什么区别呢,看下图:
到这里,发现jar包冲突了。我们编译时使用的3.0的,运行期加载的也是3.0,但是加载这个类的类加载器权限比较低,对于整个web容器里的资源,加载的这个类可能访问不到,导致出现这个问题。(注意,tomcat的类加载机制和JAVA默认的的不太一样,它先加载WEB项目的)。
解决方式一:什么都不用动,给我们自己引入的servlet-api加一个作用域
如果你不加,那么这个依赖的作用域默认是<scope>compile</scope>,作用域什么意思呢?如下:
compile:默认值,适用于所有阶段(表明该jar包在编译、运行以及测试中路径俊可见),并且会随着项目直接发布。
provided:编译和测试时有效,并且该jar包在运行时由服务器提供。如servlet-api.
runtime:运行时使用,对测试和运行有效。如jdbc.
test:只在测试时使用,在编译和运行时不起作用。发布项目时没有作用。
system:不依赖maven仓库解析,需要提供依赖的显式的置顶jar包路径。对项目的移植来说是不方便的。
作用域变成provided后,我们编译用的是我们自己引入的,而在运行时只能加载到tomcat容器的。