วันจันทร์ที่ 8 มิถุนายน พ.ศ. 2558

Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf

     เรามาพูดกันที่ส่วนของการทำ Web Framework กันครับ ซึ่ง Spring Boot มีให้เลือกใช้หลายตัวพวก Template Engine ทั้งหลาย Free Maker, Groovy, Velocity, Thymeleaf
     แล้วทำไมผมถึงเลือกใช้ Thymeleaf ล่ะ เพราะมันคือการเพิ่ม tag พิเศษของ Thymeleaf เองเข้าไปใน HTML Page เลยทำให้สามารถทำหน้า Mock Up นั้นมาใส่ข้อมูลเพิ่มได้เลย ถ้าไม่รันผ่าน Thymeleaf ก็จะเห็นเป็น HTML ธรรมดาแต่พอผ่าน Thymeleaf ก็จะเห็นที่เราใช้ขึ้นมา เราเพิ่มเพียงแค่ th:xxx ใน html tag เท่านั้น
     เรามาดูการ Config กันครับ
1. Config ให้ Spring Boot รู้จัก Thymeleaf โดยเพิ่ม spring-boot-starter-thymeleaf มาใน pom.xml
 <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-thymeleaf</artifactId>  
           </dependency>  

2. ใช้งานได้แล้ว ต่อไปเรามาทำส่วนของ Controller กันต่อ
 package tutorial.spring4.controllers;  
 import org.slf4j.Logger;  
 import org.slf4j.LoggerFactory;  
 import org.springframework.stereotype.Controller;  
 import org.springframework.ui.Model;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RequestMethod;  
 import tutorial.spring4.forms.HelloForm;  
 @Controller  
 @RequestMapping(value="/thymeleaf")  
 public class ThymeleafController {  
      private final static Logger LOG = LoggerFactory.getLogger(ThymeleafController.class);  
      @RequestMapping(method=RequestMethod.GET)  
      public String getPage(final Model model) {  
           LOG.debug("getPage(final Model model)");  
           HelloForm form = new HelloForm();  
           form.setSay("Hi");  
           form.setName("Thymeleaf");  
           model.addAttribute("thymeleaf", form);  
           return "thymeleaf";  
      }  
 }  
     จะเห็นว่าเขียนเหมือน Spring Controller ปกติเลย โดยตอน return จะถูก Mapping ด้วย /src/main/resources/templates/thymeleaf.html จะเติมให้โดยอัติโนมัติโดยไม่ต้อง Config เพิ่มเติมอะไร
     ส่วน model.addAtribute("thymeleaf", form) เราจะเอาไปใช้กับหน้าจอโดยเรียก thymeleaf

3. ต่อไปในส่วนของหน้าเวบ เราจะสร้าง thymeleaf.html โดยไปไว้ที่ src/main/resources/templates
 <!DOCTYPE html>  
 <html xmlns="http://www.w3.org/1999/xhtml"  
    xmlns:th="http://www.thymeleaf.org"  
    th:include="template :: page">  
   <head>  
     <title>Hello World Spring Boot</title>  
           <!-- initialize the pickers -->  
   </head>  
   <body>  
        <div class="starter-template" th:fragment="content">  
                 <form class="form-inline" role="form" th:object="${thymeleaf}">  
                 <div class="form-group">  
                  <label>Say : </label>  
                  <input type="text" id="hello" th:field="*{say}"/>  
                 </div>  
                 <div class="form-group">  
                  <label>Name : </label>  
                  <input type="text" id="hello" th:field="*{name}"/>  
                 </div>  
                 <button type="submit" class="btn btn-default">Submit</button>  
                </form>  
        </div>  
   </body>  
 </html>  
     - th:include คือการทำส่วนของ template โดยดึง template.html มาในส่วนของ page
     - th:fragment คือส่วนที่เราจะบอกว่าส่วนนี้ให้เอาหน้านี้มาใช้แสดงใน template
     - th:object เป็นการ Mapping Object กับ Form ของหน้าจอ
     - th:field จะ Mapping กับ field ของ thymeleaf ที่เป็น Object ของ HelloForm เช่น th:field="*{say}" จะถูก Mapping กับ field name = "say"

4. แค่นี้เราก็ใช้งานได้แล้วครับ โดยเรียกจาก /thymeleaf ที่ถูก Mapping ใน Controller

References
Basic
1. Spring Boot ตอนที่ 1 มาทำความรู้จักกับ Spring Boot
2. Spring Boot ตอนที่ 2 Hello World
3. Spring Boot ตอนที่ 3 โครงสร้างของ Project
4. Spring Boot ตอนที่ 4 Spring Boot กับ Thymeleaf
5.Spring Boot ตอนที่ 5 Spring Boot กับ Database [แบบ Embeded]
6.Spring Boot ตอนที่ 6 กับ Production Database
7.Spring Boot ตอนที่ 7 Security
8.Spring Boot ตอนที่ 8 Testing

11 comments:

ณัฐพล ทวีศรีสวัสดิ์ กล่าวว่า...

ผมเพิ่ม thymeleaf แล้ว run ไม่ได้อ่ะครับ
Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$JdbcTemplateConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath.

Naphachara Rattanwilai กล่าวว่า...

@ณัฐพล ทวีศรีสวัสดิ์ มัน Error จากติดต่อ DB น่ะครับ เอา Spring-data-jpa ออกก่อนแล้วลองเทสดูครับ

ณัฐพล ทวีศรีสวัสดิ์ กล่าวว่า...

ผมเอา
spring.thymeleaf.check-template-location=false
มาใส่ไว้ใน application.properties ไม่รู้ว่าเป็นการแก้ที่ถูกหรือป่าว แต่ว่ารันได้แล้วครับ

ณัฐพล ทวีศรีสวัสดิ์ กล่าวว่า...

จะรอติดตามอ่านเรื่อยๆนะครับ ถ้าจะให้ดีขอเป็นวิดีโอเลย ฮาฮา
ขอบคุณที่เขียนการสอนนี้ขึ้นมา ช่วยได้เยอะเลย กำลังศึกษาอยู่พอดี
ไม่เก่งอิ้ง มีภาษาไทยมาสบายเลย อิอิ

Naphachara Rattanwilai กล่าวว่า...

@ณัฐพล ทวีศรีสวัสดิ์ มี Folder /src/main/resources/templates เปล่าครับ ตัว Thymeleaf จะไปอ่านจากที่นี่น่ะครับ ลองสร้างไฟลไว้ดู แล้วเอา เช็คออก

ณัฐพล ทวีศรีสวัสดิ์ กล่าวว่า...

ได้แล้วครับ ขอบคุณครับ

ไม่ระบุชื่อ กล่าวว่า...

การ mapping with pojoclass มีขั้นตอนยังไงบ้างคับ

Naphachara Rattanwilai กล่าวว่า...

ใน controller ให้ใช้ model.addAttribute ครับ แล้ว mapping ใน th:object บนหน้าจอด้วยชื่อเดียวกัน

Sarunyoo Keawsopa กล่าวว่า...

มีใครติดเรื่อง ภาษาไทยบ้างหรือเปล่าครับ
ผมใช้ spring mvc 4 + thymeleaf 3.0.1 ในการ Test
เวลาแสดงผล เป็น ????????????? ครับ

Naphachara Rattanwilai กล่าวว่า...

กำหนดให้เป็น UTF-8 น่ะครับ

Sarunyoo Keawsopa กล่าวว่า...

กว่าจะรู้ว่า property จนครบ
เล่นเอาสะเหนือยเลยครับ

ขอบคุณครับ @Naphachara