SpringBoot第十二篇:整合jsp

追夢1819發表於2019-05-31

作者:追夢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

建立專案,我們先看看專案的結構:

SpringBoot第十二篇:整合jsp

首先,引入 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。不瞭解的讀者可以閱讀上一章



SpringBoot第十二篇:整合jsp

相關文章