第 2-2 課:Spring Boot 項目中使用 JSP

JSP(Java Server Pages,Java 服務器頁面)是一個簡化的 Servlet 設計,它是由 Sun Microsystems 公司倡導、許多公司參與一起建立的一種動態網頁技術標準。JSP 技術類似 ASP 技術,它是在傳統的網頁 HTML(標準通用標記語言的子集)文件(.html)中插入 Java 程序段(Scriptlet)和 JSP 標記(tag),從而形成 JSP 文件,後綴名爲(*.jsp)。用 JSP 開發的 Web 應用是跨平臺的,既能在 Linux 下運行,也能在其他操作系統上運行。

JSP 其實就是 Java 爲了支持 Web 開發而推出的類前端 Servlet,可以在 JSP 中寫 Java 或者 Html 語法等,後端根據 JSP 語法渲染後返回到前端顯示,在沒有模板引擎之前 JSP 是 Java 程序員開發人員的首選,到現在仍然有很多公司使用 JSP 開發後臺管理系統。本課內容將介紹如何在 Spring Boot 項目中使用 JSP。

快速上手

項目結構

首先看一下添加 JSP 支持後的項目結構:

spring-boot-jsp
 +-src
    +- main
         +- java
         +- resources
         +- webapp
              +- WEB-INF
                 +- jsp
                    +- welcome.jsp
    +- test
 +-pom.xml

對比以前的項目結構 main 目錄下多了 webapp 目錄,用來存放目錄 jsp 文件。

配置文件

需要在配置文件中指定 jsp 的位置和後綴。

spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
  • spring.mvc.view.prefix 指明 jsp 文件在 webapp 下的哪個目錄
  • spring.mvc.view.suffix 指明 jsp 以什麼樣的後綴結尾

引入依賴包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

spring-boot-starter-web 包依賴了 spring-boot-starter-tomcat 不需要再單獨配置。引入 jstl 和內嵌的 tomcat,jstl 是一個 JSP 標籤集合,它封裝了 JSP 應用的通用核心功能。tomcat-embed-jasper 主要用來支持 JSP 的解析和運行。

編寫頁面

簡單寫一個頁面:

<!DOCTYPE html>
<html lang="en">

<body>
    Time:  ${time}
    <br>
    Message: ${message}
</body>

</html>

很簡單的一個頁面,展示後端傳到頁面的時間和消息。

後端程序

@Controller
public class WelcomeController {

    @GetMapping("/")
    public String welcome(Map<String, Object> model) {
        model.put("time", new Date());
        model.put("message", "hello world");
        return "welcome";
    }

}

time 獲取當前時間,message 賦值爲 hello world。

測試

cmd 進入項目跟路徑下:

cd ...\spring-boot-jsp

執行以下命令啓動:

mvn clean spring-boot:run

啓動完成後,在瀏覽器中訪問地址:http://localhost:8080/,返回信息如下:

Time: Sat Aug 11 13:26:35 CST 2018 
Message: hello world

說明項目運行成功。

常用示例

頁面中常用的展示後端傳值、if 判斷、循環等功能,可以使用 jstl 語法處理,也可以直接寫 Java 代碼來實現這些邏輯,在 jsp 頁面中這兩種方式都支持。但不建議在 jsp 頁面中編寫大量的 Java 代碼,從而導致前端業務複雜,可讀性差等問題。下面通過一些小的示例來學習。

在 WelcomeController 類中定義一個 user() 的方法,設置一些值從後端傳遞到前端:

@GetMapping("/user")
public String user(Map<String, Object> model, HttpServletRequest request) {
    model.put("username", "neo");
    model.put("salary", 666);
    request.getSession().setAttribute("count",6);
    return "user";
}

將參數和值以鍵值對的方式存儲在 Map 中,jsp 頁面可以直接根據屬性名來獲取值,也可以通過 request 來傳遞後端屬性和值,返回值會以鍵值對的方式傳遞到 user.jsp 頁面。

在 user.jsp 文件頭部添加兩個標籤:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html lang="en">

引入第一個標籤是爲了讓頁面支持中文展示,第二個標籤引入表示頁面使用 jstl 語法來處理頁面邏輯。

Java 代碼

可以直接在 jsp 頁面中使用 Java 代碼,如果是一行 Java 代碼使用<%= %>的語法,如果是多行 Java 代碼則使用<% %>的語法,示例如下:

<h3>一行 Java 代碼</h3>
<p>
    今天的日期是: <%=(new java.util.Date())%>
</p>
<h3>多行 Java 代碼</h3>
<p>
    你的 IP 地址是:
<%
    out.println("Your IP address is " + request.getRemoteAddr()+"</br>");
    out.println("一段代碼 ");
%>
</p>

For 循環是頁面最常用的功能之一,一般用在循環展示表格、列表等。

<h3>For 循環實例</h3>
<%
    int count = (int)session.getAttribute("count");
    for ( int fontSize = 1; fontSize <=count; fontSize++){
 %>
          純潔的微笑
<br />
<%}%>

根據後端傳遞的 count 值來選擇前端頁面循環次數。

jstl 語法

頁面常常會使用一些邏輯判斷,使用 jstl 語法很容易實現這些功能。

<h3>標籤 c:if</h3>
<c:if test="${username !=null}">
<p>用戶名爲:username<p>
</c:if>

使用 jstl 標籤的<c:if>來判斷傳遞過來的 username 是否爲空,如果不爲空將 username 展示到頁面。當有多條件判斷時可以使用 <c:choose>更方便。

<h3>標籤 c:choose</h3>
<c:choose>
    <c:when test="${salary <= 0}">
    太慘了。
    </c:when>
    <c:when test="${salary > 1000}">
    不錯的薪水,還能生活。
    </c:when>
    <c:otherwise>
    什麼都沒有。
    </c:otherwise>
</c:choose>

上述代碼根據 salary 值的大小來輸出不同的內容。

jstl 語法可以支持常見的功能,這裏只是列舉最常用的兩個作爲示例。

頁面佈局

一般網站的每個頁面都擁有相同的頁眉和頁腳,這兩部分內容一般很少發生變動,這部分內容特別適合將它提取出來,讓每個頁面來重複利用。

JSP 可以通過 include 指令來實現此效果,include 指令用於在編譯階段包括一個文件,這個指令告訴容器在編譯階段,把其他外部文件的內容合併到當前 JSP 文件中,可在 JSP 頁面的任何位置使用 include 指令進行編碼。

include 有兩種用法:<%@ include file="relative url"%><jsp:include page="relative url" flush=”true”/>。前者是在翻譯階段執行,後者是在請求處理階段執行;前者叫作靜態包含,後者叫作動態包含,會在執行時檢查包含內容變化。兩者使用語法沒有太大區別,下面舉一個簡單示例。

新建一個 footer.jsp 內容如下:

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <body>
    我是頁尾
    </body>
</html>

在 user.jsp 頁面中引入 footer.jsp:

<h3>佈局</h3>
<%@include file="footer.jsp"%>

這樣在訪問 user.jsp 時,會將 footer.jsp 內容展示到 user.jsp 頁面引入的位置。

上述代碼都完成後,整體看一下頁面的效果,啓動項目在瀏覽器中輸入網址:http://localhost:8080/user,頁面展示效果如下:

調試和部署

在 IDEA 中運行

如果像其他項目一樣,直接在 IDEA 中通過 main 方法來啓動項目,在訪問測試的時候會出現 404 not found。

這是因爲 Spring Boot JSP 項目需要額外進行一個設置:選擇 Edit Configurations 選項,打開 Run/Debug Configurations:

設置 Working directory 的路徑爲項目根路徑:

然後重啓項目就可以正常的訪問到頁面內了。

在單獨的 Tomcat 中運行

(1)在 pom.xml 裏設置打包格式爲 war。

<packaging>war</packaging>

(2)排除內嵌的 Tomcat 依賴

打包時排除掉內嵌的 Tomcat 依賴,避免 jar 包衝突。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 排除內置容器,排除內置容器導出成 war 包可以讓外部容器運行spring-boot項目-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

(3)Servlet 的支持

Spring Boot 項目必須實現 SpringBootServletInitializer 接口的 configure() 方法才能讓外部容器運行 Spring Boot 項目,啓動類同目錄下創建 ServletInitializer 類:

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(JspApplication.class);
    }
}

(4)打包發佈,在項目根目錄執行 maven 命令:

mvn clean package

(5)將 war 包發佈到 Tomcat 即可。

總結

通過本課的學習我們掌握瞭如何在 Spring Boot 項目中集成 JSP,Spring Boot 支持使用內嵌的 Tomcat 來運行 JSP,也支持將項目打包成 War 包部署到獨立的 Tomcat 中。實際項目中推薦使用單獨的 Tomcat 來部署使用 JSP 的項目,內嵌的 Tomcat 還不是很穩定,偶爾會出現訪問遲緩的現象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章