天天看點

實作一個簡易版的Tomcat(十五)前言

前言

使用thymeleaf,生成動态頁面。

關于動态頁面和靜态頁面:

  • 動态資源(資料):通過程式生成的資料,比如:驗證碼。
  • 靜态資源(資料):事先準備好的,不會變的。比如圖檔,html頁面等。

本版本需求:在一個頁面上顯示所有注冊使用者的資訊。

該頁面上展示的使用者資料來源于user.dat。該檔案随着使用者做注冊修改等操作在随時變化,是以展示注冊使用者的頁面不可能是事先準備好的不變的内容。是以該頁面上的使用者資料是程式每次根據請求該頁面時生成并展現到頁面中。

thymeleaf是一個用于生成動态頁面的架構,可以在html代碼中添加少量的标簽即可和程式生成的資料進行結合,生成一個含有這些資料并且樣子還是該html代碼樣子的頁面。 

實作:

1:組建頁面上要使用的資料.

2:建立顯示資料的靜态頁面.

3:用thymeleaf将資料綁定到頁面上生成一個含有動态資料的頁面并最終響應給用戶端展示.

步驟:

1:由于之前都是靜态頁面是通過實體檔案響應用戶端,但是動态頁面不必要這麼複雜,可以直接以一組位元組響應給用戶端即可,下面是對Response類的改動:

在響應正文相關資訊下添加byte數組類型的屬性data

實作一個簡易版的Tomcat(十五)前言
實作一個簡易版的Tomcat(十五)前言
實作一個簡易版的Tomcat(十五)前言

2:定義一個業務處理類:UserListServlet,并實作sercice方法.

3:定義一個表示使用者資訊的類:User,該類每一個執行個體用于表示一個使用者.

實作一個簡易版的Tomcat(十五)前言

4:在webapps/myweb目錄下建立一個靜态頁面:userList.html

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>使用者清單</title>
    </head>
    <body>
        <center>
            <h1>使用者清單</h1>
            <table >
                <tr>
                    <td>使用者名</td>
                    <td>密碼</td>
                    <td>昵稱</td>
                    <td>年齡</td>
                </tr>
                <tr th:each="user : ${users}">
                    <td th:text="${user.username}">張三</td>
                    <td th:text="${user.password}">123456</td>
                    <td th:text="${user.nickname}">阿三</td>
                    <td th:text="${user.age}">22</td>
                </tr>
                <tr th:remove="all">
                    <td>李四</td>
                    <td>555666</td>
                    <td>老四</td>
                    <td>33</td>
                </tr>
            </table>
        </center>
    </body>
</html>
           

5:service方法中讀取user.dat檔案中的所有資料,并利用thymeleaf将資料綁定到userList.html中生成含有所有使用者資訊的頁面并響應.

由于是Tomcat的底層,是以下面的代碼會手動建立thymeleaf模闆解析器

/**
 * 展示所有使用者資訊
 *
 * 将user.dat檔案中所有使用者讀取出來并利用thymeleaf結合
 * 靜态頁面userList.html産生一個所有使用者資訊的頁面并
 * 響應給用戶端。
 * @Author JIANG
 */
public class UserListServlet {
    public void service(HttpRequest request, HttpResponse response) {
        System.out.println("UserListServlet:開始處理...");
        //1.從user.dat中讀取所有使用者資訊

        /*
         * 将User.dat檔案中所有使用者資訊讀取出來并以User對象形式儲存每一個員工資訊。
         * 最終将這些User對象存入一個List集合
         */

        List<User> list = new ArrayList<>();
        try (RandomAccessFile raf = new RandomAccessFile("user.dat","r")){
            for (int i = 0;i<raf.length()/100;i++) {
                byte[] data = new byte[32];
                raf.read(data);
                String username = new String(data,"UTF-8").trim();

                raf.read(data);
                String password = new String(data, "UTF-8").trim();

                raf.read(data);
                String nickname = new String(data, "UTF-8").trim();

                int age = raf.readInt();

                list.add(new User(username,password,nickname,age));

            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());

        //2.使用thymeleaf結合靜态頁面和資料生成動态頁面
        //模闆解釋器,用來設定模闆的基本資訊
        FileTemplateResolver re = new FileTemplateResolver();
        //模闆類型是html檔案
        re.setTemplateMode("html");
        //模闆檔案字元集,就是頁面的字元集
        re.setCharacterEncoding("UTF-8");
        //初始化模闆引擎
        TemplateEngine te = new TemplateEngine();
        te.setTemplateResolver(re);

        //準備的資料
        //Context用于儲存所有需要與頁面結合的動态資料
        Context context = new Context();
        //将儲存所有使用者資訊的List集合存入Context
        context.setVariable("users",list);

        //利用thymeleaf模闆引擎将userList.html與資料結合
        /*
         * process方法會将給定的頁面與context中的資料結合并将
         * 動态資料綁定到頁面中,該方法有傳回值,傳回的就是生成
         * 好的html代碼内容(一個String對象)
         */
        String html = te.process("./webapps/myweb/userList.html",context);

        System.out.println(html);

        //3.将動态頁面響應給用戶端
        try {
            response.setData(html.getBytes("UTF-8"));
            response.putHeader("Content-Type","text/html");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.println("UserListServlet:處理完畢!");
    }
}
           

此版本實作了第一個動态頁面,利用了thymeleaf模闆解析器将資料和頁面綁定,再通過位元組數組一同響應給用戶端,第一次實作了一個簡單的同步請求,在下一個版本中将再做一個動态頁面。