SpringBoot支持JSP访问,启动报错java.lang.NoClassDefFoundError: javax/servlet/ServletContext

SpringBoot支持JSP简介

前言:

这篇文章中, 我们将使用IntelliJ IDEA开发一个带有Spring Boot所提供的内嵌tomcat的Spring MVC 应用程序示例。 示例源码是官网下载下来。记录一下所踩过的坑。有什么疑问可以在评论区提问,谢谢。

环境:

JDK1.8

IntelliJ IDEA/Eclipse

Maven

Spring Boot 1.5.6

Spring Boot与Apache Maven 3.2兼容。
Maven 依赖
spring-boot-starter-parent:  
提供了依赖关系管理,可以省略已存在依赖的版本标签。
并声明一个或多个“启动器”的依赖关系。Spring Boot还提供了一个可选的 Maven插件来创建可执行的jar。

spring-boot-starter-parent是使用Spring Boot的好方法,但它可能不适合所有的时间。有时您可能需要从不同的父POM

继承,或者您可能不喜欢我们的默认设置。请参见 第13.2.2节“使用不带父POM的Spring Boot”作为使用import 范围的替代解

决方案。

spring-boot-starter-web: 包括了创建一个web应用程序的所有依赖。 这将避免列出不同的Spring常见的项目的版本(译注:项Web项目可能需要添加大量的依赖)。

spring-boot-starter-tomcat:默认情况下,启用一个内嵌的Apache Tomcat 7实例。 我们使用了我们定义的版本重写了这一点。 如果你需要部署War包在其他独立版本的Tomcat服务器上也可以标明。

tomcat-embed-jasper: 提供.jsp文件加载。

项目介绍:

首先,去官网翻阅了一下文档找到如下介绍,已经翻译过来,如下:

使用SpringBoot时对JSP有一些限制,然后官网有一个JSP示例,试着跑起来,目前官网推荐的springboot版本是1.5.6,

 
  1. <span style="font-size:14px;"><parent>

  2. <groupId>org.springframework.boot</groupId>

  3. <artifactId>spring-boot-starter-parent</artifactId>

  4. <version>1.5.6.RELEASE</version>

  5. </parent></span>

其它依赖:

 
  1. <!-- JSP文件需要的依赖-->

  2. <dependency>

  3. <groupId>javax.servlet</groupId>

  4. <artifactId>jstl</artifactId>

  5. </dependency>

  6. <!-- Provided -->

  7. <dependency>

  8. <groupId>org.springframework.boot</groupId>

  9. <artifactId>spring-boot-starter-tomcat</artifactId>

  10. <scope>provided</scope><!--由JDK或者容器提供-->

  11. </dependency>

  12. <dependency>

  13. <groupId>org.apache.tomcat.embed</groupId>

  14. <artifactId>tomcat-embed-jasper</artifactId>

  15. <scope>provided</scope><!--在IntellijIDEA中为provided时不会加入到Classpath中,这是IDEA的BUG->

  16. </dependency>

  17. <!-- Test -->

  18. <dependency>

  19. <groupId>org.springframework.boot</groupId>

  20. <artifactId>spring-boot-starter-test</artifactId>

  21. <scope>test</scope>

  22. </dependency>

然后试着去执行官网的JSP示例,使用的开发工具是IntellJ IDEA遇到了几个问题,如下介绍:

1、运行项目遇到了如下错误:

 
  1. Caused by: java.lang.IllegalStateException: Failed to introspect annotated methods on class

  2. org.springframework.boot.web.support.SpringBootServletInitializer

  3.  
  4. at org.springframework.core.type.StandardAnnotationMetadata.

  5. getAnnotatedMethods(StandardAnnotationMetadata.java:163) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]

  6.  
  7. at org.springframework.context.annotation.ConfigurationClassParser.

  8. retrieveBeanMethodMetadata(ConfigurationClassParser.java:380) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]

  9.  
  10. at org.springframework.context.annotation.ConfigurationClassParser.

  11. doProcessConfigurationClass(ConfigurationClassParser.java:314) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]

  12.  
  13. at org.springframework.context.annotation.ConfigurationClassParser.

  14. processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]

  15.  
  16. at org.springframework.context.annotation.ConfigurationClassParser.

  17. parse(ConfigurationClassParser.java:198) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]

  18.  
  19. at org.springframework.context.annotation.ConfigurationClassParser.

  20. parse(ConfigurationClassParser.java:167) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE]

  21. ... 17 common frames omitted

  22.  
  23. Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext

  24. at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_111]

  25. at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_111]

  26. at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_111]

  27. at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods

  28. (StandardAnnotationMetadata.java:152) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]

  29. ... 22 common frames omitted

  30.  
  31. Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext

  32. at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_111]

  33. at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_111]

  34. at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_111]

  35. at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_111]

  36. ... 26 common frames omitted

  37.  

google一番,查到了一些原因。

注意:

在Intellij IDEA中所有 scope 为 provided 的依赖都是不会被加入到 classpath 中的,目前该bug尚未被修复((bug report)。

如果你的web应用是部署到容器中的,那么这个bug不会影响使用,因为web应用中provided的依赖在容器运行时会被提供。

如果你做spring Boot开发,有带provided的依赖时,直接在IntellIJ IDEA中运行项目会导致ClassNotFound异常。

所以当jar需要被加入到classpath中需要注释<scope>provided</scope>,或者更改为:<scope>compile</scope>

Intellij Idea下运行Spring Boot关于provided依赖不加入classpath的bug与解决方案。其实这个错误有多种解决方案,下面就简单介绍一下最简单的解决方案:

插件赖如下:

 
  1. <plugin>

  2. <groupId>org.springframework.boot</groupId>

  3. <artifactId>spring-boot-maven-plugin</artifactId>

  4. </plugin>

如运行报错,指定版本<version>version number</version>版本号显示红色说明插件相关文件没有下载下来或者没有下载完整。找到maven repository删除之前不完整或者文件夹即可,重新下载。这样就完美解决了之前的问题。

指定Application的working directory:

如上述还是不能访问jsp文件,或者报错404,原因如下,继续如下操作,指定working directory:

问题:
在使用Intellij idea 时,如果配置文件放在project根目录下或者其他位置,往往会出现找不到配置文件的问题,而eclipse却不会出现这种问题。

解决方:

导致此问题的原因是因为Intellij idea 默认的根目录project的目录,而不是要运行的module目录。 
选择Edit Configurations–》Configuration–》Working directory,选择当前的module或者$MODULE_DIR$,即可解决。详情如下图: 

 

注意:

spring-boot-starter-web包括spring-boot-starter-tomcat。你可以在这里查看

spring-boot-starter-tomcat包括tomcat-embed-core。你可以在这里查看

但是,似乎tomcat-embed-core不包括tomcat-embed-jasper。其实是tomcat-embed-jasper谁包括依赖tomcat-embed-core在这里检查

无论如何,tomcat-embed-jasper标记为provided,所以表示您期望JDK或容器在运行时提供依赖关系。此范围仅适用于编译和测试类路径,不可传递。

总而言之,spring-boot-starter-web包括tomcat嵌入式的依赖关系,但它不包括jasper嵌入依赖关系,所以应该是单独声明的原因。

如有人遇到一样的问题,麻烦在评论区评论一下,谢谢。以上问题都是在使用IntelliJ IDEA的情况下所发生的错误及解决方案。项目也在eclipse运行过,没有以上问题出现。

文章来源:https://blog.csdn.net/qq496013218/article/details/76241027

猜你喜欢

转载自blog.csdn.net/w893932747/article/details/81329842