为什么 Spring 引导不支持 jsp,而如果我们添加适当的 jar 引用,它可以呈现页面



到处都写着 Spring boot 不支持 jsp 视图。在其官方文件中有三个原因

  • 使用Jetty和Tomcat,如果您使用战争包装,它应该可以工作。当使用 java -jar 启动时,可执行的战争将起作用,并且还将 可部署到任何标准容器。在以下情况下不支持 JSP 使用可执行 jar。
  • Undertow 不支持 JSP。
  • 创建自定义错误.jsp页面不会覆盖用于错误处理的默认视图。应改用自定义错误页。

对于第一项,"使用可执行 jar 时不支持 JSP"。但是当我添加对 tomcat-embed-jasper 的引用并在 application.properties 中设置正确的资源路径时,jsp 文件也可以很好地呈现。

我想这可能意味着 Spring 引导不支持 jsp,而不调用其他引用库,例如 tomcat-embed-jasper。

但是对于百里香叶,我们还必须进口弹簧启动器百里香叶。为什么我们可以说 Spring 引导支持百里叶,涉及额外的库。

那么我如何理解文档中的第一项呢?

嵌入式 Tomcat 包(在 springboot 中用于创建可执行 jar)默认情况下不包含 JSP,我们还必须添加模块“org.apache.tomcat.embed:tomcat-embed-jasper”。这就是为什么我们在 springboot 中添加tomcat-embed-jasper作为依赖项的原因,以便我们可以在 jsp 中使用 jstl 标签。

*jar用作打包时,springboot 不能与 jsp 作为视图解析器正常工作的主要原因是因为Tomcat 中的硬编码文件模式。问题是,当您使用java -*.jar部署 springboot 应用程序时,jsp 文件将不会出现在嵌入式 tomcat 中,并且在尝试为请求提供服务时,您将获得404 页面未找到。这是因为 jar 打包,jsp 文件不会从WEB-INF文件夹中复制。如果在使用 jar 作为打包时将 jsp 文件保存在META-INF/resources文件夹下,它应该可以工作。

Thymeleaf允许使用模板作为原型,这意味着它们可以被视为静态文件并放入resources/templates文件夹中供弹簧拾取。但是jsp文件会有jstl标签等,在渲染之前需要由jasper转译,所以根据我的知识,它们不能设置为静态文件。

使用WAR(Web应用程序存档)时,打包将自动从以下项目结构中获取资源:

|-- pom.xml
`-- src
`-- main
|-- java
|   `-- com
|       `-- example
|           `-- projects
|               `-- SampleAction.java
|-- resources
|   `-- images
|       `-- sampleimage.jpg
`-- webapp
|-- WEB-INF
|   `-- web.xml
|-- index.jsp
`-- jsp
`-- websource.jsp

使用带有 jsp 的 springboot 的指南和官方示例:指南、示例存储库

WAR 打包结构坚持将 jsp 文件保存在webapp/文件夹下,它将按预期工作。maven 战争目标会将文件从 webapp 文件夹复制到WEB-INF,所有资源文件(如 jsp)都将是战争打包的根源。从这里开始,maven-re打包目标或 spring boot 重新打包负责使 jar/war 可执行。因此,如果文件存在于 原始战争 ,它也将在可执行文件中。springboot 可执行的战争结构如下:

example.war
|
+-META-INF
|  +-MANIFEST.MF
+-org
|  +-springframework
|     +-boot
|        +-loader
|           +-<spring boot loader classes>
+-WEB-INF
+-classes
|  +-com
|     +-mycompany
|        +-project
|           +-YourClasses.class
+-lib
|  +-dependency1.jar
|  +-dependency2.jar
+-lib-provided
+-servlet-api.jar
+-dependency3.jar

所以对于评论:

如果您将 jsp 文件放在文件夹src/main/resources中,则放入此目录中的任何内容都将根据WAR文档自动复制到WEB-INF/classes

所以,如果你把你的jsp文件保存在src/main/resources下,并在yml或属性文件中配置以下内容,它应该适用于WAR档案。我还没有尝试过,所以不确定。

spring.mvc.view.prefix = /WEB-INF/classes/templates
spring.mvc.view.suffix = .jsp

谢谢孙彦宏,

我添加了pomorg.apache.tomcat.embed:tomcat-embed-jasper并编译了.war,我的docker图像可以识别我的jsps

如果你选择使用 JSP。事实证明,Java servlet容器(包括嵌入式Tomcat和Jetty容器)通常会在/WEB-INF下的某个地方寻找JSP。但是,如果您将应用程序构建为可执行的 JAR 文件,则无法满足该要求。因此,JSP 仅在以下情况下是一个选项 您正在将应用程序构建为 WAR 文件并将其部署在传统的 Servlet 中 容器。如果要构建可执行的JAR文件,则必须选择Thymeleaf, FreeMarker,或其他选项之一

最新更新