Serving Web Content with Spring MVC
ตัวอย่างนี้เป็นตัวอย่างที่อ่านและทดลองทำจากบทความต้นฉบับนี้ Serving Web Content with Spring MVC โดยใช้เครื่องมือคือ Spring Tool Suite
Stack
- ระบบปฎิบัติการที่ใช้ : Ubuntu 14.04
- เครื่องมือ : Spring Tool Suite 3.6.3
- Java JDK 7 update 65 (1.7.0_65)
- เวลาที่ใช้ : ประมาณ 45 นาที (รวมการอ่าน ทำความเข้าใจด้วย)
สร้างโปรเจ็ค
เปิด Spring Tool Suite ขึ้นมา จากนั้นทำการ Import โปรเจ็ค โดยค้นหา “Serving web content”
- Build Type : เลือกเป็น Gradle
เมื่อ Import ได้แล้ว จะเห็นโปรเจ็คอยู่สองตัว คือ
- gs-serving-web-content-initial
- gs-serving-web-content-complete
ตัว gs-serving-web-content-initial เป็นโปรเจ็คเปล่าๆ เราจะใช้ตัวนี้ ส่วนอีกตัว gs-serving-web-content-complete เป็นโปรเจ็คที่เสร็จแล้ว เผื่อเอาไว้ดูเปรียบเทียบว่าเราทำตรงไหนผิดพลาด
สร้าง Web Controller
ใน Spring, ตัว Controller จะเป็นตัวควบคุม HTTP request ต่างๆ ง่ายๆ โดยการใส่ annotation @Controller
อย่างเช่น ตัวอย่าง GreetingController
เป็นตัวจัดการ GET
สำหรับ /greeting
โดย return เป็น ชื่อของ View
กลับมาเพื่อทำการ render เป็น HTML
ไฟล์ /src/main/java/hello/GreetingController.java
@RequestMapping
: เป็น annotation สำหรับ mapping ระหว่าง HTTP request/greeting
กับเมธอดgreeting()
@RequestParam
: จะทำการ bind ค่าจาก query String parametername
เข้ากับ parametername
ของเมธอดgreeting()
โดย query String parameter เซตค่าrequired
เป็น false คือไม่บังคับว่าจะต้องมีหรือไม่มีก็ได้ ถ้าไม่มีก็จะใช้ค่าdefaultValue
แทน โดยค่าของname
ก็จะถูกเพิ่มเข้าไปในออปเจ็คModel
เพื่อสามารถเข้าถึงได้ในหน้า View Template (ใช้ Thymeleaf)
@RequestMapping
โดย default นั้น map ทุก HTTP reqeust เช่นGET
,PUT
,POST
ถ้าเราจะเจาะจงว่าจะ map เฉพาะGET
ก็ทำได้เช่น@ReqeustMapping(method=GET)
ต่อมาที่ไฟล์ src/main/resources/templates/greeting.html
ทำการเพิ่มโค๊ดด้านล่างลงไป
ไฟล์ html ด้านบนนี้จะใช้ view technology ในเคสนี้คือ Themeleaf เพื่อทำการเรนเดอร์ HTML ข้อดีคือเราสามารถที่จะเข้าถึงตัวแปร ออปเจ็คของ Java ผ่านหน้า HTML ได้ เช่น
xmlns:th="http://www.thymeleaf.org"
: เป็นการกำหนด xml schema โดยเวลาจะใช้ thymeleaf ก็แค่ใช้ตัวย่อว่าth
th:text
: เป็น expression ที่ทำการ render ค่า parameter${name}
จาก controller
สร้างคลาส Application
เปิดไฟล์ src/main/java/hello/Application.java
ขึ้นมา แล้วเพิ่มโค๊ดด้านล่างนี้ลงไป
เมธอด main()
จะมี SpringApplication
ทำการรันคลาส Application
โดยใช้ component ใน ApplicationContext
เป็นตัวจัดการ ตัว @ComponentScan
เป็น annotation ที่บอก Spring ให้ทำการค้นหา แพคเกต hello
ว่ามีคลาสไหนทำการ register @Component
ไว้บ้าง
ซึ่งจะเห็นได้ว่า คลาส GreetingController
ได้ทำการ register ไว้เพราะว่ามี @Controller
อยู่ (@Controller
เป็นส่วนหนึ่งของ @Component
annotation @EnableAutoConfiguration
เป็นการตั้งค่า auto configuration ให้เราเองโดยตัว DispatcherServlet โดยที่ไม่ต้องมีไฟล์ web.xml
เลย
Test the Service
ทดสอบรันโปรแกรม Run As => Spring Boot App ตัว Spring Boot App จะทำการรันโดยใช้ Tomcat Server
เมื่อ start Application เรียบร้อยแล้ว ก็เปิด Browser แล้วเข้าหน้า URL นี้ http://localhost:8080/greeting จะเห็นข้อมูลด้านล่างนี้ปรากฎอยู่
สามารถส่ง parameter ก็ได้เช่นกัน โดยตัวอย่าง ส่ง name
เป็น query string parameter จะได้ URL ดังนี้ http://locahost:8080/greeting?name=Devahoy จะเห็นได้ว่าผลลัพธ์เปลี่ยนไปแล้ว จาก Hello, World!
เป็น Hello, Devahoy!
แสดงว่า @RequestParam
ใน GreetingController
นั้นทำงานได้ตามที่เราคาดหวัง โดย parameter name
ค่า default มันคือคำว่า “World” แต่เมื่อไหร่ที่เราส่ง parameter มาด้วย มันก็จะไป override ค่า default และใช้ค่า parameter ของเราเอง
สรุปจากบทความนี้
@RequestMapping
: map HTTP request กับเมธอดใน Java@RequestParam
: ไว้ bind ค่า query string parameter กับ String หรือ Object@Controller
: เป็น component เพื่อ handle HTTP request โดยมีHttpServletRequest
และHttpServletResponse
@ComponentScan
: เอาไว้ค้นหาทั้งแพคเกจ เพื่อหา component ที่ใช้ในโปรเจ็คSpringApplication
: เอาไว้สั่ง launch ตัว Spring Application จาก main classTomcat
: เป็น Servlet Container ที่เอาไว้รัน Spring ได้Spring Boot
: เป็น stand-alone สำหรับ Spring โดยรวม Tomcat, Jetty เข้าไปด้วย (ไม่ต้อง deploy โดยใช้ ไฟล์ WAR)thymeleaf
: เป็น Template Engine ที่สามารถ render ออปเจ็คของ Java ในไฟล์ HTML ได้ คล้ายๆ Handlebars, Jade หรือ erb ของ Ruby
สิ่งที่ต้องเรียนรู้เพิ่มเติม
- อ่าน API และ Reference เพิ่มเติม
- ไปค้นคว้าเกี่ยวกับ Themeleaf ต่อ
- ลองสร้างโปรเจ็คแบบ Command Line ไม่ใช้ IDE โดยใช้ Gradle/Maven และ Text Editor
Reference
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust