错误描述
这是错误信息
javax.servlet.ServletException: Class com.lihaixu.servlet.DemoServlet is not a Servlet
在 maven 项目中 配置好了tomcat 但是访问资源时候报错
写的命名是一个Servlet
解决
主要是没有配置好POM.XML 造成的
<!--添加servlet的依赖jar包-->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
上方代码中 确实是导入了 Servlet的依赖 但是忽略了一个大问题
没有加依赖范围
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
加上<scope>provided</scope>
这一行即可
原因详解
造成的原因可能是
在tomcat中(虽然只是用的插件)有一个servlet-api的jar包了 如果这里再次使用就会形成冲突
系统不知道该宠哪个 直接报错了
加上这一行<scope>provided</scope>
给这个依赖一个范围,就可以了。
依赖范围讲解
A 依赖 B,需要在 A 的 pom.xml 文件中添加 B 的坐标,添加坐标时需要指定依赖范围,依赖范围包括:
-
compile:编译范围,指 A 在编译时依赖 B,此范围为默认依赖范围。编译范围的依赖会用在编译、测试、运行,由于运行时需要所以编译范围的依赖会被打包。
-
provided:provided 依赖只有在当 JDK 或者一个容器已提供该依赖之后才使用, provided 依赖在编译和测试时需要,在运行时不需要,比如:servlet api 被 tomcat 容器提供。
-
runtime:runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如:jdbc的驱动包。由于运行时需要所以 runtime 范围的依赖会被打包。
-
test:test 范围依赖 在编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用,比如:junit。由于运行时不需要所以 test范围依赖不会被打包。
-
system:system 范围依赖与 provided 类似,但是你必须显式的提供一个对于本地系统中 JAR文件的路径,需要指定 systemPath 磁盘路径,system依赖不推荐使用。
图解
在 maven-web 工程中测试各各 scop。
测试总结:
- 默认引入 的 jar 包 ——- compile 【默认范围 可以不写】(编译、测试、运行 都有效 )
- servlet-api 、jsp-api ——- provided (编译、测试 有效, 运行时无效 防止和 tomcat 下 jar 冲突)
- jdbc 驱动 jar 包 —- runtime (测试、运行 有效 )
- junit —– test (测试有效)
依赖范围由强到弱的顺序是:compile > provided > runtime > test