0%

SpringBoot使用jsp

Spring Boot 使用 JSP 详解:从依赖配置到视图渲染全流程

虽然 Spring Boot 推荐使用 Thymeleaf、Freemarker 等模板引擎,但在迁移传统 SSH/SSM 项目时,仍需支持 JSP 视图。由于 Spring Boot 对 JSP 的支持并非默认集成,需手动配置依赖、资源路径和视图解析器。从 “依赖配置→目录结构→视图解析→常见问题” 四个维度,详细讲解 Spring Boot 集成 JSP 的完整流程,帮你顺利实现 JSP 页面渲染。

核心背景:为什么 Spring Boot 不默认支持 JSP?

Spring Boot 推荐使用 嵌入式容器(如 Tomcat)和 可执行 JAR 打包,而 JSP 存在两个关键限制,导致其未被默认支持:

  1. JSP 编译依赖 Servlet 容器:JSP 需要 Tomcat 的 jasper 引擎编译为 Servlet 类,而嵌入式 Tomcat 默认不包含 jasper 依赖;
  2. JAR 包无法直接包含 JSP:JSP 文件需放在 WEB-INF 目录下,而 Spring Boot 默认的 JAR 打包结构中没有 WEB-INF,需手动配置资源路径映射。

因此,集成 JSP 的核心是 “添加 JSP 编译依赖” 和 “配置 JSP 资源目录”。

Spring Boot 集成 JSP 的完整步骤

步骤 1:添加 JSP 相关依赖

需引入两个核心依赖:tomcat-embed-jasper(JSP 编译引擎)和 jstl(JSP 标准标签库,可选但推荐)。

Maven 依赖配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<dependencies>
<!-- 1. Spring Boot Web 依赖(包含嵌入式 Tomcat) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 2. JSP 编译引擎(嵌入式 Tomcat 需手动引入) -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!-- scope 无需设置为 provided,嵌入式 Tomcat 需要加载该依赖 -->
</dependency>

<!-- 3. JSTL 标签库(可选,使用 JSP 标签时需引入,如 c:forEach) -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
<exclusions>
<!-- 排除旧的 servlet-api 依赖,避免冲突 -->
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
依赖说明:
  • tomcat-embed-jasper:提供 JSP 编译功能,嵌入式 Tomcat 必须依赖此包才能解析 JSP;
  • jstl-api + jstl-impl:支持 JSP 标准标签(如 c:outc:forEach),避免页面中使用原始 Java 代码(如 <%= ... %>)。

步骤 2:创建 JSP 资源目录

Spring Boot 默认的资源目录(src/main/resources)不支持 JSP,需手动创建传统 Web 项目的 src/main/webapp 目录(存放 JSP 文件),并通过 Maven 配置将其映射到 JAR/WAR 的正确路径。

1. 创建目录结构

在项目根目录下创建以下目录(与 src/main/resources 同级):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
src/
└── main/
├── java/ # 源码目录
│ └── com/xxx/demo/
│ ├── controller/ # Controller 层
│ └── DemoApplication.java # 主程序类
├── resources/ # 配置文件目录
│ └── application.yml # 配置文件
└── webapp/ # JSP 资源目录
├── WEB-INF/ # 安全目录(JSP 建议放在此处,避免直接访问)
│ └── views/ # JSP 视图目录
│ └── index.jsp # JSP 页面
└── static/ # 静态资源(CSS/JS/图片,可选)
└── css/
└── style.css
2. 配置 Maven 资源映射

pom.xmlbuild 标签中添加配置,将 src/main/webapp 目录下的资源(JSP、静态文件)映射到打包后的 META-INF/resources 目录(嵌入式 Tomcat 会扫描此目录加载资源):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<build>
<!-- 项目打包名称(如 demo-jsp.war) -->
<finalName>demo-jsp</finalName>

<!-- 配置 JSP 及静态资源的打包路径 -->
<resources>
<!-- 1. 映射 JSP 及 webapp 下的所有资源 -->
<resource>
<directory>src/main/webapp</directory>
<!-- 打包后存放的路径(必须是 META-INF/resources) -->
<targetPath>META-INF/resources</targetPath>
<!-- 包含的文件类型(所有文件) -->
<includes>
<include>**/*.*</include>
</includes>
</resource>

<!-- 2. 保留默认的 resources 目录配置(配置文件、静态资源) -->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>

<!-- 3. Maven 编译插件(确保 JDK 版本兼容) -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

关键说明

  • targetPath 必须设置为 META-INF/resources,否则嵌入式 Tomcat 无法找到 JSP 文件;
  • 若不配置此步骤,打包后 JSP 文件会丢失,访问时会报 “404 找不到页面” 错误。

步骤 3:配置 JSP 视图解析器

通过配置文件(application.ymlapplication.properties)指定 JSP 页面的 “前缀” 和 “后缀”,让 Spring MVC 知道如何根据逻辑视图名找到物理 JSP 文件。

1. YML 配置(推荐):
1
2
3
4
5
6
7
8
9
10
spring:
mvc:
# 配置 JSP 视图解析器
view:
prefix: /WEB-INF/views/ # JSP 文件的物理路径前缀(对应 src/main/webapp/WEB-INF/views/)
suffix: .jsp # JSP 文件的后缀
# 可选:配置静态资源映射(若静态文件放在 webapp/static 下,可省略此配置)
web:
resources:
static-locations: classpath:/META-INF/resources/static/
2. Properties 配置:
1
2
3
4
5
6
# JSP 视图解析器
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

# 静态资源映射(可选)
spring.web.resources.static-locations=classpath:/META-INF/resources/static/

视图解析逻辑
若 Controller 返回逻辑视图名 index,Spring MVC 会根据配置拼接为物理路径:
prefix + 逻辑视图名 + suffix/WEB-INF/views/index.jsp,最终找到 src/main/webapp/WEB-INF/views/index.jsp 文件。

步骤 4:编写 Controller 和 JSP 页面

1. 编写 Controller(跳转 JSP 页面)

创建 IndexController,返回逻辑视图名,触发 JSP 渲染:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.xxx.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller // 注意:使用 @Controller(返回视图),而非 @RestController(返回 JSON)
public class IndexController {

// 访问 /index 跳转 JSP 页面
@GetMapping("/index")
public String index(Model model) {
// 向 JSP 页面传递数据(Model 会自动放入请求域)
model.addAttribute("username", "张三");
model.addAttribute("age", 25);
// 返回逻辑视图名 "index",对应 /WEB-INF/views/index.jsp
return "index";
}
}
2. 编写 JSP 页面(src/main/webapp/WEB-INF/views/index.jsp

使用 JSP 语法和 JSTL 标签渲染页面,获取 Controller 传递的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 引入 JSTL 核心标签库(需先添加 JSTL 依赖) -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
<title>Spring Boot JSP 示例</title>
<!-- 引入静态资源(CSS),路径对应 src/main/webapp/static/css/style.css -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/style.css">
</head>
<body>
<h1>Hello, Spring Boot JSP!</h1>
<!-- 从 Model 中获取数据(请求域中的 username 和 age) -->
<p>用户名:${username}</p>
<p>年龄:${age}</p>

<!-- 使用 JSTL 标签(循环示例) -->
<h3>爱好列表:</h3>
<c:forEach items="${['篮球', '足球', '读书']}" var="hobby">
<p>${hobby}</p>
</c:forEach>
</body>
</html>
3. 编写静态资源(src/main/webapp/static/css/style.css
1
2
3
4
5
6
7
8
h1 {
color: #2c3e50;
text-align: center;
}
p {
color: #34495e;
font-size: 16px;
}

步骤 5:启动应用并访问

  1. 启动 Spring Boot 应用(通过 main 方法或 mvn spring-boot:run);
  2. 访问地址:http://localhost:8080/index(默认端口 8080,若修改需对应调整);
  3. 预期效果:页面正常显示 “Hello, Spring Boot JSP!”,并渲染出用户名、年龄和爱好列表,CSS 样式生效。

关键注意事项(避免踩坑)

1. 打包方式:优先使用 WAR 而非 JAR(可选)

虽然通过上述配置,JSP 可在 JAR 包中运行,但 Spring Boot 对 JSP 的 JAR 打包支持存在局限性(如部分服务器环境无法识别)。若需部署到外置 Tomcat,建议将打包方式改为 WAR:

1. 修改 pom.xml 打包类型:
1
2
<!-- 将打包方式从 jar 改为 war -->
<packaging>war</packaging>
2. 排除嵌入式 Tomcat(外置 Tomcat 部署时):

若部署到外置 Tomcat,需排除 Spring Boot 内置的 Tomcat 依赖,避免冲突:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排除嵌入式 Tomcat 依赖 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- 外置 Tomcat 需提供 Servlet API 依赖(编译时需要) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
3. 改造启动类(外置 Tomcat 部署):

需继承 SpringBootServletInitializer,重写 configure 方法(适配外置 Tomcat 的启动逻辑):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

// 外置 Tomcat 启动时调用此方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DemoApplication.class);
}
}

2. 避免使用 @RestController 注解

@RestController@Controller + @ResponseBody 的组合,会将返回值直接转为 JSON / 字符串,而非跳转视图。若需跳转 JSP,Controller 必须使用 @Controller 注解。

错误示例(无法跳转 JSP):

1
2
3
4
5
6
7
8
// 错误:@RestController 会返回 "index" 字符串,而非跳转 JSP
@RestController
public class IndexController {
@GetMapping("/index")
public String index() {
return "index"; // 返回字符串 "index",不是视图名
}
}

正确示例

1
2
3
4
5
6
7
@Controller // 正确:返回逻辑视图名,触发 JSP 跳转
public class IndexController {
@GetMapping("/index")
public String index() {
return "index"; // 返回视图名 "index",对应 /WEB-INF/views/index.jsp
}
}

3. JSP 文件路径必须正确

JSP 文件的物理路径需与 spring.mvc.view.prefix 配置一致,否则会报 “404 找不到页面” 错误:

  • 若配置 prefix: /WEB-INF/views/,JSP 必须放在 src/main/webapp/WEB-INF/views/ 下;
  • 避免将 JSP 放在 src/main/resources 目录(该目录仅用于配置文件和静态资源,嵌入式 Tomcat 不扫描此目录的 JSP)。

4. 静态资源访问路径

若静态资源(CSS/JS/ 图片)放在 src/main/webapp/static/ 下,访问时需通过 ${pageContext.request.contextPath}/static/xxx 拼接路径,避免硬编码上下文路径:

正确访问方式(动态获取上下文路径):

1
2
3
4
<!-- ${pageContext.request.contextPath} 会自动填充应用上下文路径(如 /demo-jsp) -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/style.css">
<script src="${pageContext.request.contextPath}/static/js/main.js"></script>
<img src="${pageContext.request.contextPath}/static/img/logo.png" alt="Logo">

错误访问方式(硬编码路径,上下文路径变化时失效):

1
2
<!-- 错误:若应用上下文路径为 /demo-jsp,此路径会指向 /static/css/style.css,而非 /demo-jsp/static/css/style.css -->
<link rel="stylesheet" href="/static/css/style.css">

常见问题与解决方案

1. 访问 JSP 报 404 错误

问题原因:
  • JSP 文件路径与 prefix 配置不匹配;
  • Maven 资源映射未配置,JSP 未打包到 META-INF/resources
  • 使用 @RestController 而非 @Controller
解决方案:
  • 核对 JSP 路径是否为 src/main/webapp/WEB-INF/views/(与 prefix 一致);
  • 检查 pom.xmlresources 配置,确保 targetPathMETA-INF/resources
  • 控制器改用 @Controller 注解。

2. JSTL 标签无法识别(报 “未知标签” 错误)

问题原因:
  • 未添加 JSTL 依赖(jstl-apijstl-impl);
  • JSP 页面未引入 JSTL 标签库(缺少 <%@ taglib %> 指令)。
解决方案:
  • 确保已添加 JSTL 依赖;

  • 在 JSP 页面顶部添加标签库引入:

    1
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

3. 静态资源(CSS/JS)无法加载(404 错误)

问题原因:
  • 静态资源路径配置错误;
  • 访问路径未包含应用上下文路径。
解决方案:
  • 确认静态资源放在 src/main/webapp/static/ 下;
  • 访问时使用 ${pageContext.request.contextPath}/static/xxx 动态拼接路径。

4. 外置 Tomcat 部署后 JSP 无法访问

问题原因:
  • 未排除嵌入式 Tomcat 依赖,导致冲突;
  • 启动类未继承 SpringBootServletInitializer
  • WAR 包未放在外置 Tomcat 的 webapps 目录下。
解决方案:
  • 排除 spring-boot-starter-tomcat 依赖,添加 javax.servlet-api 依赖;
  • 启动类继承 SpringBootServletInitializer 并实现 configure 方法;
  • 将 WAR 包放入外置 Tomcat 的 webapps 目录,启动 Tomcat 自动解压部署。

总结

Spring Boot 集成 JSP 的核心是 “补全 JSP 依赖” 和 “配置资源路径”,关键步骤可概括为:

  1. 添加 tomcat-embed-jasper 和 JSTL 依赖;
  2. 创建 src/main/webapp 目录,配置 Maven 资源映射到 META-INF/resources
  3. 通过 spring.mvc.view 配置 JSP 视图解析器的前缀和后缀;
  4. 使用 @Controller 编写控制器,返回逻辑视图名;
  5. webapp/WEB-INF/views 下编写 JSP 页面,通过 Model 传递数据

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10