整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          SpringBoot系列(六)thymeleaf完整詳細版

          1. thymeleaf簡介
          2. thymeleaf特點
          3. thymeleaf在SpringBoot的應用
          4. SpringBoot引入Thymeleaf
          5. controller配置
          6. thymeleaf頁面測試編寫
          7. 結果展示
          8. 其他thymeleaf語法


          1. thymeleaf簡介

          ?1. Thymeleaf是適用于Web和獨立環境的現代服務器端Java模板引擎。

          ?2. Thymeleaf的主要目標是為您的開發工作流程帶來優雅的自然模板 -HTML可以在瀏覽器中正確顯示,也可以作為靜態原型工作,從而可以在開發團隊中加強協作。

          ?3. Thymeleaf擁有適用于Spring Framework的模塊,與您喜歡的工具的大量集成以及插入您自己的功能的能力,對于現代HTML5 JVM Web開發而言,Thymeleaf是理想的選擇-盡管它還有很多工作要做。

          2. thymeleaf特點

          ?1. thymeleaf在有網絡無網絡的環境下都可以運行,所以可以直接在瀏覽器打開查看靜態頁面效果。它支持HTML原型,可以在HTML標簽里面添加其他屬性來實現數據渲染。

          ?2. thymeleaf具有開箱即用的特性,Thymeleaf是Spring boot推薦使用的模版引擎,直接以html顯示,前后端可以很好的分離。

          3. thymeleaf在SpringBoot的應用

          ?1. 國際化,渲染不同國家的語言

          ?2. 共同頁面顯示,比如統一異常頁面處理,共同的頁面處理

          4. SpringBoot引入Thymeleaf

          ?新建一個Springboot web項目,然后添加以下依賴。

          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-thymeleaf</artifactId>
          </dependency>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web</artifactId>
          </dependency>
          

          ?然后在配置文件里面添加如下依賴。

          spring:
            thymeleaf:
              cache: false 
              prefix: classpath:/templates/
              encoding: UTF-8 #編碼
              suffix: .html #模板后綴
              mode: HTML #模板
          

          配置說明:

          ?cache這一行是將頁面的緩存關閉,不然我們改變頁面之后可能不能及時看到更改的內容,默認是true。

          ?prefix是配置thymeleaf模板所在的位置。

          ?encoding 是配置thymeleaf文檔的編碼,后面的就不說了

          5. controller配置

          ?上面我們配置好了環境之后就可以創建一個controller文件夾,然后寫一個controller,來測試我們的thymeleaf是否成功引入。順便創建一個對象。 代碼:

          @Controller
          public class ThymeleafController {
          
              @GetMapping("/getStudents")
              public ModelAndView getStudent(){
                  List<Student> students = new LinkedList<>();
                  Student student = new Student();
                  student.setId(1);
                  student.setName("全棧學習筆記");
                  student.setAge(21);
                  Student student1 = new Student();
                  student1.setId(2);
                  student1.setName("張三");
                  student1.setAge(22);
                  students.add(student);
                  students.add(student1);
                  ModelAndView modelAndView = new ModelAndView();
                  modelAndView.addObject("students",students);
                  modelAndView.setViewName("students");
                  return modelAndView;
              }
          }
          

          ?代碼解釋 :我們創建一個list,然后在list里面添加數據,一遍一次將數據傳到頁面使用。然后我們創建一個ModelAndView的對象,將list放入這個modeAndView對象中,第一個參數是需要放到model中的屬性名稱相當于是一個鍵,第二個是,是一個對象。然后利用setViewName方法,設置要跳轉的頁面或者說是將數據傳到對應的頁面。

          ?最外層我們使用了一個 @Controller,這個注解是用來返回一個頁面或者視圖層的。

          ?當然,返回ModelAndView對象只是一種方法,還有其他的方法,比如說下面這樣

          @RequestMapping("/getString")
          public String getString(HttpServletRequest request){
              String name = "全棧學習筆記";
              request.setAttribute("name",name);
              return "index.html";
          }
          

          利用http的request傳值。 然后還有這樣

          @RequestMapping("/getModel")
          public String getModel(Model model){
              model.addAttribute("key","這是一個鍵");
              return "index.html";
          }
          

          ?去掉末尾的.html也可以,因為我們在配置文件里面設置了文件的格式為HTML文件。return的字符串都是對應的HTML文件的名稱。

          ?實體類代碼如下:

          /**
           * (Student)實體類
           *
           * @author 全棧學習筆記
           * @since 2020-04-14 11:39:10
           */
          public class Student  {
              private static final long serialVersionUID = -91969758749726312L;
              /**
              * 唯一標識id
              */
              private Integer id;
              /**
              * 姓名
              */
              private String name;
              /**
              * 年齡
              */
              private Integer age;
              //省略get,set方法,自己加上
          }
          

          6. 頁面編寫

          ?寫好代碼就等頁面了,在templates文件夾下面創建一個students.html文件,編寫如下代碼

          <!DOCTYPE html>
          <html lang="en" xmlns:th="https://www.thymeleaf.org/">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
          <table border="1">
              <tr>
                  <td>ID</td>
                  <td>姓名</td>
                  <td>年齡</td>
              </tr>
              <tr th:each="student:${students}">
                  <td th:text="${student.id}"></td>
                  <td th:text="${student.name}"></td>
                  <td th:text="${student.age}"></td>
              </tr>
          </table>
          </body>
          </html>
          

          ?這里有一個很重要的事情就是,我們使用thymeleaf模板之前必須先引入thymeleaf,如下。

          <html lang="en" xmlns:th="https://www.thymeleaf.org/">
          

          ?這個很關鍵,不然你就用不了這個thymeleaf語法規則。

          ?代碼說明:你可以看到th:each 這個語法,是用來遍歷的,類似于for循環,然后我們通過th:text 這個語法來渲染文字。

          7.測試結果顯示

          ?運行項目,瀏覽器輸入localhost:8089/getStudents


          8.thymeleaf常用的語法

          常用的語法:

          <!-- 對象 -->
          <div th:object="${student}">
              <p th:text="id"></p>
              <p th:text="name"></p>
              <p th:text="age"></p>
          </div>
          <!-- 邏輯判斷 -->
          th:if
          th:else
          <!-- 分支控制 -->
          th:switch
          th:case
          
          <!--循環 -->
          th:each
          <!-- 運算 -->
          <p th:text="${age}%2 == 0"></p>
          <!-- 賦制value -->
          th:value
          <!-- 鏈接 -->
          th:href
          

          本期講解就到這里,如果你覺得本文對你有用,可以點個贊,點個關注哦!下一期更精彩!wx search 全棧學習筆記!點個關注不迷路。

          文地址:https://dwz.cn/2UR4feq8

          作者:yizhiwazi

          學習目標

          • 快速掌握Thymeleaf的基本使用(五大基礎語法+常用內置對象)

          使用教程

          溫馨提示:Thymeleaf 最為顯著的特征是增強屬性,任何屬性都可以通過th:xx 來完成交互,例如th:value最終會覆蓋value屬性。

          一、基礎語法

          變量表達式 ${}

          使用方法:直接使用th:xx = "${}" 獲取對象屬性 。例如:

          <form id="userForm">
           <input id="id" name="id" th:value="${user.id}"/>
           <input id="username" name="username" th:value="${user.username}"/>
           <input id="password" name="password" th:value="${user.password}"/>
          </form>
          <div th:text="hello"></div>
          <div th:text="${user.username}"></div>
          

          選擇變量表達式 *{}

          使用方法:首先通過th:object 獲取對象,然后使用th:xx = "*{}"獲取對象屬性。

          這種簡寫風格極為清爽,推薦大家在實際項目中使用。 例如:

          <form id="userForm" th:object="${user}">
           <input id="id" name="id" th:value="*{id}"/>
           <input id="username" name="username" th:value="*{username}"/>
           <input id="password" name="password" th:value="*{password}"/>
          </form>
          

          鏈接表達式 @{}

          使用方法:通過鏈接表達式@{}直接拿到應用路徑,然后拼接靜態資源路徑。例如:

          <script th:src="@{/webjars/jquery/jquery.js}"></script>
          <link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css">
          

          片段表達式 ~{}

          片段表達式是Thymeleaf的特色之一,細粒度可以達到標簽級別,這是JSP無法做到的。

          片段表達式擁有三種語法:

          • ~{ viewName } 表示引入完整頁面
          • ~{ viewName ::selector} 表示在指定頁面尋找片段 其中selector可為片段名、jquery選擇器等
          • ~{ ::selector} 表示在當前頁尋找

          使用方法:首先通過th:fragment定制片段 ,然后通過th:replace 填寫片段路徑和片段名。例如:

          <!-- /views/common/head.html-->
          <head th:fragment="static">
           <script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
          </head>
          <!-- /views/your.html -->
          <div th:replace="~{common/head::static}"></div>
          

          在實際使用中,我們往往使用更簡潔的表達,去掉表達式外殼直接填寫片段名。例如:

          <!-- your.html -->
          <div th:replace="common/head::static"></div>
          

          值得注意的是,使用替換路徑th:replace 開頭請勿添加斜杠,避免部署運行的時候出現路徑報錯。(因為默認拼接的路徑為spring.thymeleaf.prefix = classpath:/templates/)

          消息表達式

          即通常的國際化屬性:#{msg} 用于獲取國際化語言翻譯值。例如:

           <title th:text="#{user.title}"></title>
          

          其它表達式

          在基礎語法中,默認支持字符串連接、數學運算、布爾邏輯和三目運算等。例如:

          <input name="name" th:value="${'I am '+(user.name!=null?user.name:'NoBody')}"/>
          

          二、內置對象

          官方文檔: 附錄A: Thymeleaf 3.0 基礎對象

          官方文檔: 附錄B: Thymeleaf 3.0 工具類

          七大基礎對象:

          • ${#ctx} 上下文對象,可用于獲取其它內置對象。
          • ${#vars}: 上下文變量。
          • ${#locale}:上下文區域設置。
          • ${#request}: HttpServletRequest對象。
          • ${#response}: HttpServletResponse對象。
          • ${#session}: HttpSession對象。
          • ${#servletContext}: ServletContext對象。

          常用的工具類:

          • #strings:字符串工具類
          • #lists:List 工具類
          • #arrays:數組工具類
          • #sets:Set 工具類
          • #maps:常用Map方法。
          • #objects:一般對象類,通常用來判斷非空
          • #bools:常用的布爾方法。
          • #execInfo:獲取頁面模板的處理信息。
          • #messages:在變量表達式中獲取外部消息的方法,與使用#{...}語法獲取的方法相同。
          • #uris:轉義部分URL / URI的方法。
          • #conversions:用于執行已配置的轉換服務的方法。
          • #dates:時間操作和時間格式化等。
          • #calendars:用于更復雜時間的格式化。
          • #numbers:格式化數字對象的方法。
          • #aggregates:在數組或集合上創建聚合的方法。
          • #ids:處理可能重復的id屬性的方法。

          三、迭代循環

          想要遍歷List集合很簡單,配合th:each 即可快速完成迭代。例如遍歷用戶列表:

          <div th:each="user:${userList}">
           賬號:<input th:value="${user.username}"/>
           密碼:<input th:value="${user.password}"/>
          </div>
          

          在集合的迭代過程還可以獲取狀態變量,只需在變量后面指定狀態變量名即可,狀態變量可用于獲取集合的下標/序號、總數、是否為單數/偶數行、是否為第一個/最后一個。例如:

          <div th:each="user,stat:${userList}" th:class="${stat.even}?'even':'odd'">
           下標:<input th:value="${stat.index}"/>
           序號:<input th:value="${stat.count}"/>
           賬號:<input th:value="${user.username}"/>
           密碼:<input th:value="${user.password}"/>
          </div>
          

          如果缺省狀態變量名,則迭代器會默認幫我們生成以變量名開頭的狀態變量 xxStat, 例如:

          <div th:each="user:${userList}" th:class="${userStat.even}?'even':'odd'">
           下標:<input th:value="${userStat.index}"/>
           序號:<input th:value="${userStat.count}"/>
           賬號:<input th:value="${user.username}"/>
           密碼:<input th:value="${user.password}"/>
          </div>
          

          四、條件判斷

          條件判斷通常用于動態頁面的初始化,例如:

          <div th:if="${userList}">
           <div>的確存在..</div>
          </div>
          

          如果想取反則使用unless 例如:

          <div th:unless="${userList}">
           <div>不存在..</div>
          </div>
          

          五、日期格式化

          使用默認的日期格式(toString方法) 并不是我們預期的格式:Mon Dec 03 23:16:50 CST 2018

          <input type="text" th:value="${user.createTime}"/>
          

          此時可以通過時間工具類#dates來對日期進行格式化:2018-12-03 23:16:50

          <input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"/>
          

          六、內聯寫法

          • (1)為什么要使用內聯寫法?·答:因為 JS無法獲取服務端返回的變量。
          • (2)如何使用內聯表達式?答:標準格式為:[[${xx}]] ,可以讀取服務端變量,也可以調用內置對象的方法。例如獲取用戶變量和應用路徑:
           <script th:inline="javascript">
           var user = [[${user}]];`
           var APP_PATH = [[${#request.getContextPath()}]];
           var LANG_COUNTRY = [[${#locale.getLanguage()+'_'+#locale.getCountry()}]];
           </script>
          
          • (3)標簽引入的JS里面能使用內聯表達式嗎?答:不能!內聯表達式僅在頁面生效,因為Thymeleaf只負責解析一級視圖,不能識別外部標簽JS里面的表達式。

          七、國際化

          需要了解更多關于國際化的精彩描述請前往 SpringBoot 快速實現國際化i18n 。

          例如在國際化文件中編寫了user.title這個鍵值,然后使用#{}讀取這個KEY即可獲取翻譯。

           <title th:text="#{user.title}">用戶登陸</title>
          

          八、詳細教程

          ======== 有了上述基礎后 下面正式開始Thymeleaf 的詳細教程 ==============

          首先通過Spring Initializr創建項目,如圖所示:

          然后在POM文件引入web 、thymeleaf等依賴:

          <dependencies>
           <dependency><!--Web相關依賴-->
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
           </dependency>
           <dependency><!--頁面模板依賴-->
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-thymeleaf</artifactId>
           </dependency>
           <dependency><!--熱部署依賴-->
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-devtools</artifactId>
           <scope>runtime</scope>
           </dependency>
           </dependencies>
          

          然后在src/main/resources/application.yml 配置頁面路徑:

          spring:
           thymeleaf:
           cache: false #關閉緩存
           prefix: classpath:/views/ #調整頁面路徑
          

          接著在src/main/java/com/hehe/web/UserController 獲取用戶信息:

          @RestController
          public class UserController {
           private List<User> userList = new ArrayList<>();
           {
           userList.add(new User("1", "socks", "123456", new Date()));
           userList.add(new User("2", "admin", "111111", new Date()));
           userList.add(new User("3", "jacks", "222222", null));
           }
           @GetMapping("/")
           public ModelAndView index() {
           return new ModelAndView("user/user", "userList", userList);
           }
          }
          public class User {
           private String id;
           private String username;
           private String password;
           private Date createTime;
           //請讀者自行補充 構造器和 get/set方法..
          }
          

          開始編寫公共頁面:src/main/resources/views/common/head.html ,其中static為頁面片段:

          <!DOCTYPE html>
          <html xmlns:th="http://www.thymeleaf.org">
          <!--聲明static為頁面片段名稱-->
          <head th:fragment="static">
           <link th:href="@{/webjars/bootstrap/css/bootstrap.css}" rel="stylesheet" type="text/css"/>
           <script th:src="@{/webjars/jquery/jquery.js}"></script>
          </head>
          </html>
          

          接著編寫用戶列表頁:src/main/resources/views/user/user.html 配合th:each顯示用戶列表信息。

          使用說明:這里 th:replace="common/head::static" 表示將引用${spring.thymeleaf.prefix}/common/head.html的static頁面片段,值得注意的是由于替換路徑默認會拼接前綴路徑,所以開頭切勿在添加斜杠,否則在打包成JAR部署運行時將提示報Templates not found... 。

          <!DOCTYPE html>
          <html xmlns:th="http://www.thymeleaf.org">
          <head>
           <meta charset="UTF-8"/>
           <title th:text="用戶信息">User</title>
           <!--默認拼接前綴路徑,開頭請勿再添加斜杠,防止部署運行報錯!-->
           <script th:replace="common/head::static"></script>
          </head>
          <body>
          <div th:each="user,userStat:${userList}" th:class="${userStat.even}?'even':'odd'">
           序號:<input type="text" th:value="${userStat.count}"/>
           賬號:<input type="text" th:value="${user.username}"/>
           密碼:<input type="password" th:value="${user.password}"/>
           時間:<input type="text" th:value="${user.createTime}"/>
           時間:<input type="text" th:value="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm:ss')}"/>
          </div>
          <script th:inline="javascript">
           //通過內聯表達式獲取用戶信息
           var userList = [[${userList}]];
           console.log(userList)
          </script>
          </body>
          </html>
          

          然后編寫單個用戶頁面:

          至此大功告成,然后快速啟動項目,如圖所示:

          快速啟動項目

          然后訪問用戶列表: http://localhost:8080 ,如圖所示:

          然后訪問單個用戶: http://localhost:8080/user/1 ,如圖所示:

          • 入相關依賴
           <!--引入thymeleaf與Spring Security整合的依賴-->
           <dependency>
           <groupId>org.thymeleaf.extras</groupId>
           <artifactId>thymeleaf-extras-springsecurity4</artifactId>
           <version>3.0.2.RELEASE</version>
           </dependency>
           <!--引入Spring Security依賴-->
           <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-security</artifactId>
           </dependency>
           <!--引入Thymeleaf依賴-->
           <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-thymeleaf</artifactId>
           </dependency>
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          
          • 創建自定義WebSecurityConfigurerAdapter并重寫configure方法
          @EnableWebSecurity
          public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
           //攔截請求
           @Override
           protected void configure(HttpSecurity http) throws Exception {
           //設置哪些url允許被某種角色訪問
           http.authorizeRequests().antMatchers("/").permitAll()
           .antMatchers("/bronze").hasRole("英勇黃銅")
           .antMatchers("/silver").hasRole("不屈白銀")
           .antMatchers("/gold").hasRole("榮耀黃金")
           .antMatchers("/platinum").hasRole("華貴鉑金")
           .antMatchers("/diamond").hasRole("璀璨鉆石")
           .antMatchers("/master").hasRole("超凡大師")
           .antMatchers("/challenger").hasRole("最強王者");
           //啟用登錄功能,可以使用默認的登錄頁,這里使用自定義的login.html頁面
           http.formLogin().loginPage("/login");
           //啟用注銷功能,(需要提供一個action為/logout的form)并設置注銷后訪問的url,這里注銷后跳轉到首頁
           http.logout().logoutSuccessUrl("/");
           //啟用rememberMe功能,將用戶信息保存在cookie中
           http.rememberMe();
           }
           //授權認證
           @Override
           protected void configure(AuthenticationManagerBuilder auth) throws Exception {
           //inMemoryAuthentication表示使用基于內存的驗證,還可以使用基于數據庫的驗證等,使用BCrypt編碼對密碼進行加密
           //,否則報錯java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
           auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("bronze")
           .password(new BCryptPasswordEncoder().encode("0110")).roles("英勇黃銅")
           .and().withUser("silver").password(new BCryptPasswordEncoder()
           .encode("0110")).roles("不屈白銀").and().withUser("gold")
           .password(new BCryptPasswordEncoder().encode("0110")).roles("榮耀黃金")
           .and().withUser("platinum").password(new BCryptPasswordEncoder()
           .encode("0110")).roles("華貴鉑金").and().withUser("diamond")
           .password(new BCryptPasswordEncoder().encode("0110")).roles("璀璨鉆石")
           .and().withUser("master").password(new BCryptPasswordEncoder()
           .encode("0110")).roles("超凡大師").and().withUser("challenger")
           .password(new BCryptPasswordEncoder().encode("0110")).roles("最強王者");
           }
          }
          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
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          
          • 主頁顯示
          <div align="center" style="margin-top: 15px" sec:authorize="!isAuthenticated()">
           <h4 style="color: blue;">歡迎您,親愛的召喚師!<a th:href="@{/login}"> 請登錄</a></h4>
          </div>
          <div align="center" style="margin-top: 15px" sec:authorize="isAuthenticated()">
           <h4 style="color: blue;">召喚師 <span sec:authentication="name"></span>
           ! 您的段位為:<span sec:authentication="principal.authorities"></span>
           </h4>
           <form th:action="@{/logout}" method="post">
           <input type="submit" th:value="注銷登錄">
           </form>
          </div>
          <div align="center" style="margin-top: 100px" sec:authorize="hasRole('英勇青銅')">
           <a th:href="@{/bronze}">點擊領取英勇青銅段位獎勵</a>
          </div>
          <div align="center" style="margin-top: 100px" sec:authorize="hasRole('不屈白銀')">
           <a th:href="@{/silver}">點擊領取不屈白銀段位獎勵</a>
          </div>
          <div align="center" style="margin-top: 100px" sec:authorize="hasRole('榮耀黃金')">
           <a th:href="@{/gold}">點擊領取榮耀黃金段位獎勵</a>
          </div>
          <div align="center" style="margin-top: 100px" sec:authorize="hasRole('華貴鉑金')">
           <a th:href="@{/platinum}">點擊領取華貴鉑金段位獎勵</a>
          </div>
          <div align="center" style="margin-top: 100px" sec:authorize="hasRole('璀璨鉆石')">
           <a th:href="@{/diamond}">點擊領取璀璨鉆石段位獎勵</a>
          </div>
          <div align="center" style="margin-top: 100px" sec:authorize="hasRole('超凡大師')">
           <a th:href="@{/master}">點擊領取超凡大師段位獎勵</a>
          </div>
          <div align="center" style="margin-top: 100px" sec:authorize="hasRole('最強王者')">
           <a th:href="@{/challenger}">點擊領取最強王者段位獎勵</a>
          </div>
          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
          
          • 點擊領取獎勵頁面
          <div align="center" style="margin-top: 20px">
           <a th:href="@{/}">返回首頁</a>
          </div>
          <div align="center" style="margin-top: 100px">
           <h3>您在本賽季段位為:<span style="color: aqua;font-style: italic">英勇黃銅</span></h3>
           <h4>獲得皮膚獎勵:<span style="color: peru">銹跡斑斑 布里茨</span></h4>
          </div>
          1
          2
          3
          4
          5
          6
          7
          8
          
          • 自定義登錄頁面
          <div align="center" style="margin-top: 60px">
           <form th:action="@{/login}" method="post">
           <p>
           <label>Username</label>
           <input type="text" th:name="username">
           </p>
           <p>
           <label>Password</label>
           <input type="password" th:name="password">
           </p>
           <p>
           <label>Remember Me</label>
           <input type="checkbox" th:name="remember-me">
           </p>
           <div align="center">
           <input type="submit" th:value="登錄">
           </div>
           </form>
          </div>
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          
          測試結果:
          • 首頁


          • 登錄頁,點擊Remember Me下次訪問不需要重新登錄


          • 登錄成功


          • 獎勵頁面

          主站蜘蛛池模板: 国产天堂一区二区综合| 亚洲AV综合色一区二区三区| 中文字幕一区在线观看| 日本免费电影一区| 色屁屁一区二区三区视频国产| 国产成人av一区二区三区在线| 国产产一区二区三区久久毛片国语| 国产嫖妓一区二区三区无码| 香蕉免费看一区二区三区| 亚洲一区二区三区电影| 精品一区二区三区在线播放 | 五月婷婷一区二区| 国产伦精品一区二区免费| 亚洲福利视频一区二区三区| 中文字幕精品一区二区2021年 | 色噜噜狠狠一区二区三区果冻| 亚州AV综合色区无码一区| 一区二区三区在线播放视频| 无码精品人妻一区二区三区免费看 | 高清一区二区三区视频| 无码aⅴ精品一区二区三区浪潮| 在线免费视频一区| 亚洲国产精品一区二区久久| 国产成人精品一区二区三区| 亚洲日韩中文字幕无码一区| 精品成人一区二区三区四区| 成人区人妻精品一区二区三区| 美女视频在线一区二区三区| 制服美女视频一区| 国产精品无码一区二区三区不卡 | 国内偷窥一区二区三区视频| 丰满爆乳无码一区二区三区| 久久国产精品亚洲一区二区| 无码精品人妻一区二区三区免费 | 中文字幕一区二区三区乱码| 色一乱一伦一区一直爽| 正在播放国产一区| 日本免费一区尤物| 日韩AV片无码一区二区不卡| 免费看无码自慰一区二区| 亚洲乱码av中文一区二区 |