SpringBoot打包JAR后访问JSP显示白标错误页问题咨询
我明白你遇到的困扰——本地直接运行Spring Boot应用时JSP能正常加载,但打包成JAR后就出现了白标错误。这个问题核心在于Spring Boot 1.5.x版本对JAR包中JSP的支持有局限性,官方本身也不推荐在JAR中使用JSP,因为嵌入式Tomcat默认不会扫描JAR内部的JSP资源。下面给你几个可行的解决方案:
1. 修正依赖配置,确保JSP引擎被打包进JAR
首先检查你的pom.xml,Tomcat的JSP编译引擎依赖不能标记为provided(这个scope的依赖不会被打包进JAR,而嵌入式Tomcat运行时必须依赖它):
<dependencies> <!-- JSP编译引擎,必须包含在JAR包内 --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <!-- 去掉provided,或显式设置为compile --> </dependency> <!-- JSTL标签库依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> </dependencies>
2. 自定义Tomcat配置,让它能找到JAR中的JSP
嵌入式Tomcat默认不会扫描JAR内的WEB-INF/jsp目录,你需要通过配置类手动指定资源映射:
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.apache.catalina.Context; @Configuration public class TomcatJspConfig { @Bean public TomcatEmbeddedServletContainerFactory tomcatContainerFactory() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); // 自定义Tomcat上下文,添加JSP资源的映射规则 factory.addContextCustomizers((Context context) -> { // 将/WEB-INF/jsp路径映射到classpath下的META-INF/resources/WEB-INF/jsp/目录 context.getResources().addResourceSet( "/WEB-INF/jsp", "classpath:/META-INF/resources/WEB-INF/jsp/" ); }); return factory; } }
3. 确保JSP文件被正确打包进JAR
检查Maven资源配置,确保src/main/resources下的JSP文件被复制到JAR的对应目录。在pom.xml的build节点添加以下配置:
<build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
打包完成后,可以解压JAR包确认META-INF/resources/WEB-INF/jsp/目录下是否存在你的JSP文件。
4. 更稳妥的替代方案:打包成WAR文件
既然Spring Boot 1.5.x对JAR中的JSP支持有限,更可靠的方式是将项目打包为WAR文件,这也是官方推荐的JSP使用方式:
步骤1:修改打包类型
在pom.xml中把packaging改为war:
<packaging>war</packaging>
步骤2:添加SpringBootServletInitializer子类
创建一个类继承SpringBootServletInitializer,用于支持WAR部署:
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { // 替换为你的Spring Boot主类 return application.sources(YourApplication.class); } }
步骤3:调整JSP存放路径
将JSP文件从src/main/resources/META-INF/resources/WEB-INF/jsp/移到src/main/webapp/WEB-INF/jsp/目录下,视图解析器的前缀和后缀保持不变:
spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp
这样无论是将WAR部署到外部Tomcat,还是用java -jar运行嵌入式Tomcat,JSP都能正常访问。
内容的提问来源于stack exchange,提问作者Atul Dwivedi

