作者:追夢1819
原文:https://www.cnblogs.com/yanfei1819/p/10953600.html
版權宣告:本文為博主原創文章,轉載請附上博文連結!
引言
SpringBoot 雖然官方推薦使用 thymelaf 模板引擎,但是也支援jsp,只不過需要做一些修改。本文將講解 JSP 在 SpringBoot 中的應用。
說句題外話,本章的話題,比較複雜,也寫得比較累。因為 SpringBoot 並不推薦使用 JSP。據我的瞭解,SpringBoot 和 JSP 整合的專案少之又少。從而,網上這方面的資料比較少。已經存在的資源,內容基本上都是亂七八糟,或者是遠離主題的一些東西。
本章在理解的基礎上,做了一一求證,希望不會誤導讀者,浪費讀者的時間。同時,有更加了解這一塊的讀者,歡迎聯絡作者一起交流交流。
版本資訊
- JDK:1.8
- SpringBoot :2.1.4.RELEASE
- maven:3.3.9
- 外部Tomcat : 9.0
- IDEA:2019.1.1
使用內嵌Tomcat
建立專案,我們先看看專案的結構:
首先,引入 maven 依賴:
<!--對 web 的支援-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--解析jsp-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!--jstl標籤-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<scope>provided</scope>
</dependency>
注意,跟 jsp 相關的兩個依賴將其設定為 <scope>provided</scope>
。這裡我們講解一下 scope 的概念:
依賴範圍就是用來控制依賴和三種classpath(編譯classpath,測試classpath、執行classpath)的關係,Maven有如下幾種依賴範圍:
- compile:編譯依賴範圍。如果沒有指定,就會預設使用該依賴範圍。使用此依賴範圍的Maven依賴,對於編譯、測試、執行三種classpath都有效。典型的例子是spring-code,在編譯、測試和執行的時候都需要使用該依賴;
- test: 測試依賴範圍。使用次依賴範圍的Maven依賴,只對於測試classpath有效,在編譯主程式碼或者執行專案的使用時將無法使用此依賴。典型的例子是Jnuit,它只有在編譯測試程式碼及執行測試的時候才需要;
- provided:已提供依賴範圍。使用此依賴範圍的Maven依賴,對於編譯和測試classpath有效,但在執行時候無效。典型的例子是servlet-api,編譯和測試專案的時候需要該依賴,但在執行專案的時候,由於容器以及提供,就不需要Maven重複地引入一遍。
其次,需要在配置檔案 application.properties 中配置SpringBoot 對 jsp 的支援,SpringBoot 預設不支援 jsp。
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
然後,建立測試介面:
@Controller
public class JSPController {
@RequestMapping(value = "/index",method = RequestMethod.GET)
public String index(Model model){
model.addAttribute("name","SpringBoot");
return "index";
}
}
啟動類不變:
@SpringBootApplication
public class JspDemoApplication {
public static void main(String[] args) {
SpringApplication.run(JspDemoApplication.class, args);
}
}
最後,需要注意的是,要執行的是 war,而不是 jar,因為 jar 預設不會將 jsp 複製進去。故,我們需要在 pom.xml 檔案中,修改包的型別:
<packaging>jar</packaging>
修改為 <packaging>war</packaging>
。
啟動時要注意,專案打包方式是war包,不要通過 main 方法啟動。這裡用的容器是SpringBoot 內嵌的Tomcat,可以進入 war 包的目錄下,通過命令啟動:java -jar xxx.war
,訪問 http://localhost:8082/index
,可以得到對應的頁面。
外部容器
使用外部的 Tomcat 容器時,不能直接部署上面的 war 包,需要對以上程式進行改造。
1、修改啟動類
整合 SpringBootServletInitializer ,並繼承以下方法:
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemoApplication.class);
}
外部容器是以類似於web.xml檔案配置的方式來啟動Spring應用上下文,並非 main 函式。以上的的改造類似在web.xml中配置負責初始化Spring應用上下文的監聽器。
2、修改相關的依賴
專案部署在外部容器中,會與內嵌的 Tomcat 衝突,需要解決,不然啟動會報錯。本文列舉兩個解決方案:
1) 移出內嵌的 Tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
並將解析 jsp 的 jar 包 scope 設定為 provided,即:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
2) 新增以下依賴(推薦)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
作者推薦這種解決方案,它同時適合命令列啟動,以及部署到外部容器中。
總結
本文是分析 SpringBoot 中使用 JSP。JSP相對於模板引擎來說,效能更好。但是,儘管如此,作者並不推薦這種做法,而儘量使用模板引擎 Thymelaf。不瞭解的讀者可以閱讀上一章。