如何解决无论我做什么,Spring Boot应用程序中的JSP都会产生404错误
首先,我会说我已经查看并尝试了有关此问题的每个问题的解决方案。最大的问题是这些解决方案中的大多数都非常老旧,并且在过去几年中,Spring Boot发生了很大变化。需要明确的是,我尝试了this,this,this,this等。我也阅读了许多教程。什么都行不通。
我有一个全新的Spring Boot应用程序,我正在尝试使其使用JSP渲染。这些是我的依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>[2.3.4.RELEASE,3)</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>[2.3.4.RELEASE,3)</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>[2.3.4.RELEASE,3)</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>[2.8.0,3)</version>
</dependency>
<dependency>
<groupId>de.mkammerer</groupId>
<artifactId>argon2-jvm</artifactId>
<version>[2.7,3)</version>
</dependency>
<dependency>
<groupId>MysqL</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>[8.0.21,9)</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>[2.3.2,)</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>[2.3.4.RELEASE,3)</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>[9.0.38,)</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>[2.3.4.RELEASE,3)</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
我的项目的布局如下:
- source
- production
- java
- [my source code packages]
- resources
- WEB-APP
- jsp
- initialization
- begin.jsp
- [my resource packages]
- test
- java
- resources
“ WEB-APP / jsp”只是我尝试过的最新迭代。我已经尝试过“ WEB-INF / jsp”,“ meta-inf / jsp”,“ webapp / jsp”,没有父级(仅“ jsp”)等,所有这些都具有相同的结果。
我知道父目录有点不规范,但是在Maven中配置正确,并且我已经确认它不是问题的根源。
<build>
<sourceDirectory>source/production/java</sourceDirectory>
<resources>
<resource>
<directory>source/production/resources</directory>
</resource>
</resources>
...
</build>
我的应用程序类如下:
@SpringBootApplication(scanBasePackages="com.my.project")
@EnableWebMvc
@EnableJpaRepositories("com.my.project.repository")
@EntityScan("com.my.project.model")
public class Application
{
private static final Logger LOGGER = LogManager.getLogger(Application.class);
public Application()
{
}
@Bean
public ViewResolver viewResolver()
{
LOGGER.info("Constructing InternalResourceViewResolver[JstlView]");
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-APP/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
resolver.setRedirectContextRelative(true);
resolver.setRedirectHttp10Compatible(false);
return resolver;
}
public static void main(final String[] args)
{
SpringApplication.run(Application.class,args);
}
}
还有我的控制器:
@Controller
public class InitializationController
{
private static final Logger LOGGER = LogManager.getLogger(InitializationController.class);
@GetMapping("/initialize_application")
public String beginInitialization(ModelMap model)
{
LOGGER.info("Beginning initialization");
...
LOGGER.info("Returning view");
return "initialization/begin";
}
...
}
在启动时,我看到“ Constructing InternalResourceViewResolver”日志条目(创建了我的视图解析器bean)。当我转到/initialize_application
时,出现以下错误:
Whitelabel Error Page
This application has no explicit mapping for /error,so you are seeing this as a fallback.
Sun Oct 18 21:45:26 CDT 2020
There was an unexpected error (type=Not Found,status=404).
再次查看日志,我看到“开始初始化”和“返回视图”,因此我知道404是针对我的JSP而不是我的控制器的。我的控制器正在工作。
我尝试过的其他事情:
- 最初,我的申请中没有
@EnableWebMvc
。没有它,除了我的日志语句外,日志为空。当我添加@EnableWebMvc
时,现在使用404:No mapping for GET /WEB-APP/jsp/initialization/begin.jsp
(或我尝试过的除“ WEB-APP”以外的任何其他目录)记录的日志。 - 我尝试使用
mvn spring-boot:run
在纯命令行上直接运行它
- 我尝试使用Maven运行配置和命令
spring-boot:run
(相同的结果)在IntelliJ IDEA中运行它 - 我已经尝试过
<packaging>jar</packaging>
和<packaging>war</packaging>
,但是两者都没有什么不同,因为JAR和WAR都没有。 Maven直接在target/classes
目录之外运行该应用程序,而不创建工件。 - 当我尝试使用
WEB-INF
或meta-inf
而不是WEB-APP
或webapp
或其他方法时,我看到了一条已记录的警告:Path with "WEB-INF" or "meta-inf": [WEB-INF/jsp/initialization/begin.jsp]
我还确认了我的JSP存在于target/classes/WEB-APP/jsp
(或我尝试过的除“ WEB-APP”之外的任何其他目录)中,因此它们存在。 >
我不知所措。我开始认为我需要放弃Spring Boot并坚持使用带有Servlet配置和Tomcat安装的传统样板Spring Web MVC应用程序,但是我对Spring Boot的“运行”方面感到非常兴奋。任何帮助将不胜感激。
更新1
在阅读this Spring documentation about JSP limitations之后,我现在知道必须使用<packaging>war</packaging>
,并且现在正在使用它,但是并没有什么不同。我开始怀疑这里的根本问题是maven spring-boot:run
不会创建WAR并运行它,它只是将所有内容构建到target/classes
并从那里运行。
此外,在找到this old,official Spring boot samples application之后,我对项目结构做了一些更改:
- source
- production
- java
- [my source code packages]
- resources
- [my resource packages]
- webapp
- meta-inf
- WEB-INF
- jsp
- initialization
- begin.jsp
- test
- java
- resources
更新了我的视图解析器配置:
resolver.setPrefix("/jsp/");
resolver.setSuffix(".jsp");
并将其添加到我的POM中:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<warSourceDirectory>source/production/webapp</warSourceDirectory>
</configuration>
</plugin>
如果我运行mvn package
,则可以正确创建我的WAR(所有类和JSP都应该在其中创建),但是mvn spring-boot:run
和mvn package spring-boot:run
都无法工作-我仍然遇到404错误,无法解决JSP。
上面链接到的旧的Spring Boot示例应用程序将JSP放在WEB-INF/jsp
中,但是我不能这样做,因为这会导致警告Path with "WEB-INF" or "meta-inf": [WEB-INF/jsp/initialization/begin.jsp]
(仍然是404)。令人沮丧的是,此示例应用程序已不存在,也没有任何新的变体。我找不到适用于最新版本的Spring Boot的任何更新版本。该示例应用程序已在2.2.x中删除。
解决方法
您可以尝试将tomcat-embed-jasper
的范围更改为provided
吗,因为编译JSP需要此依赖性。
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>[9.0.38,)</version>
<scope>provided</scope>
</dependency>
编辑:
我在互联网上寻找各种spring-boot + jsp
项目。我注意到他们也拥有spring-boot-starter-tomcat
范围的provided
。你可以试试这个吗?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>[2.3.4.RELEASE,3)</version>
<scope>provided</scope>
</dependency>
参考文献:
https://mkyong.com/spring-boot/spring-boot-hello-world-example-jsp/
https://dzone.com/articles/spring-boot-2-with-jsp-view
Edit-2:
所以这次我创建了一个新的springboot项目。没有做最少的设置来呈现jsp。所以基本上我遵循了这个tutorial并且我的项目运行良好。
然后,我用您的替换了pom.xml,并且出现了您在问题中提到的相同错误。
然后,在进行反复试验时,我从<version>[9.0.38,)</version>
中移除了<artifactId>tomcat-embed-jasper</artifactId>
,它开始为我服务。
<!--I have removed version here and it started working for me-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!-- <version>[9.0.38,)</version>-->
<scope>provided</scope>
</dependency>
尽管我有不同的目录结构。但是正如您提到的,这不是问题的原因。
我已将项目上传到github。随时将其拉到本地运行。
,假设您的Web内容位于以下位置(应位于类路径AFAIK之外)source/production/webapp
。通过DocumentRoot
中的硬编码路径(从命令行或IDE运行时,Spring Boot会检测目录),Spring Boot将忽略此设置(在构建战争并运行该路径时将起作用)。
作为一种解决方法,您可以添加TomcatContextCustomizer
作为bean来检测路径并将其设置为正确的基准。
package com.my.project;
@SpringBootApplication
public class Application extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(DemoApplication.class);
}
public static void main(final String[] args) {
SpringApplication.run(Application.class,args);
}
@Bean
public TomcatContextCustomizer docBaseCustomizer()
{
return new TomcatContextCustomizer()
{
public void customize(Context context)
{
File root = new File("source/production/webapp");
if (root.exists() && root.isDirectory())
{
context.setDocBase(root.getAbsolutePath());
}
}
}
}
}
现在将以下内容添加到您的application.properties
spring.mvc.view.prefix=/jsp/
spring.mvc.view.suffix=.jsp
注意::只有在您的@SpringBootApplication
注释类在com.my.project
包中时,才能删除其他注释。然后它将自动检测其他类(例如实体和存储库)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。