JAKARTA STRUTS FRAMEWORK (ตอนที่ 4)
ตัวอย่างต่อไปนี้จะอนุญาตให้ผู้ใช้ใส่เงื่อนไขในการสืบค้นข้อมูลพนักงานลงในหน้า employee_search_form.jsp แล้วกดปุ่ม Search อินพุตพารามิเตอร์จะถูกดึงขึ้นมาตรวจสอบที่หน้า employee_search.jsp และหน้า employee_search.jsp จะเรียกใช้ Bean จากคลาส HRManager เพื่อสั่งให้ช่วยค้นหาพนักงานที่ตรงกับเงื่อนไขที่กำหนด รายการพนักงานทั้งหมดที่ตรงกับเงื่อนไขจะถูกส่งไปแสดงผลที่หน้า employee_search_result.jsp



ข้อเสียอีกอย่างหนึ่งของวิธีนี้ก็คือ เมื่อมีงานบางอย่างที่ต้องทำทุกครั้งก่อนที่เข้าไปรันหน้าเว็บจะต้องแก้ไขไฟล์ JSP ทุกไฟล์ ตัวอย่างของงานประเภทนี้เช่น การตรวจสอบระดับสิทธิ์ของผู้ใช้ ซึ่งต้องตรวจสอบก่อนเข้าใช้ในทุกๆหน้า ถ้าเราใช้ Model 1 เราจะต้องเพิ่มกระบวนการตรวจสอบตรงนี้เข้าไปในไฟล์ JSP ทุกไฟล์ ซึ่งเป็นงานที่ลำบากและเกิดข้อผิดพลาดได้ง่าย
4.2 JSP Model 2
1. ทุกครั้งที่มี HTTP Request เข้ามาจากไคลเอ็นต์ จะต้องส่งมาที่ Servlet ตัวหนึ่ง ที่ทำหน้าที่เป็น Controller เสมอ ตัว Controller นี้จะมีเพียงตัวเดียวเท่านั้น
2. Controller ดึงพารามิเตอร์มาตรวจดูว่าสมควรส่งต่อให้ Bean ตัวไหนรับงานไปทำดี แล้วเรียกใช้ Bean ให้ทำงานให้ เมื่อ Bean ทำงานเสร็จแล้วจะส่งผลลัพธ์กลับมาให้ Controller
3. Controller เลือกว่าจะส่งผลลัพธ์ไปแสดงที่ JSP ไหน แล้วส่งผลลัพธ์ไปแสดงผล โดยใช้วิธี redirect หรือ forward
ตัวอย่าง 8 การประยุกต์ใช้ Model 2 กับการค้นหารายการพนักงาน
ตัวอย่างนี้เป็นกรณีศึกษาเดียวกันกับในตัวอย่าง Model 1 ข้างต้น แต่เปลี่ยนจากการรับรีเควสต์ด้วยไฟล์ employee_search.jsp มาเป็นรับรีเควสต์ด้วย Servlet ที่ชื่อว่า ControllerServlet แทน ดังนี้
ซอร์สโค้ด 1-16 ไฟล์ ControllerServlet.java

ซอร์สโค้ด 1-17 ไฟล์ web.xml ที่กำหนด url pattern
ซอร์สโค้ด 1-18 ไฟล์ employee_search_form2.jsp
5. MVC Design Pattern
จากตัวอย่างของ JSP Model 2 ที่กล่าวมาแล้วข้างต้น จะตรงกับคอนเซ็ปต์ของ MVC ที่ใช้ในการออกแบบระบบ GUI (Graphical User Interface) ทั่วไปในปัจจุบัน MVC เริ่มต้นใช้งานครั้งแรกในภาษา Smalltalk และปัจจุบันถูกนำไปประยุกต์ใช้ในอีกหลายๆ Framework เนื่องจากการออกแบบแบบ MVC จะทำให้ออบเจกต์ที่ทำงานในระบบมีหน้าที่ที่ชัดเจนยิ่งขึ้น
1. Model ทำหน้าที่เป็นข้อมูล ซึ่งโครงสร้างของออบเจกต์ที่เป็นโมเดล จะเป็นไปตามโครงสร้างข้อมูลที่ใช้อยู่ในระบบงานจริงๆ โครงสร้างออบเจกต์โมเดลไม่จำเป็นเปลี่ยนไปตามรูปแบบการแสดงผลที่วิว จากภาพจะเห็นว่าข้อมูลถูกเก็บอยู่ในลักษณะตาราง และเมื่อโมเดลมีการเปลี่ยนแปลง ก็จะแจ้งให้วิวทุกตัวที่กำลังแสดงผลโมเดลนี้อยู่ จัดการอัพเดตตัวเองให้ตรงกับข้อมูลในโมเดล
2. View ทำหน้าที่แสดงผลในรูปแบบที่ผู้ใช้ต้องการ การแสดงผลส่วนใหญ่จะเป็นไปตามที่ผู้ใช้กำลังใช้งานอยู่ในปัจจุบัน และผู้ใช้แต่ละคนอาจจะมีวิวต่างกันไปตามที่กำลังทำงานอยู่ วิวจะต้องอัพเดตให้ตรงกับข้อมูลที่อยู่ในโมเดล โดยโมเดลจะแจ้งเหตุการณ์เปลี่ยนแปลงเข้ามาเอง ตัวอย่างของวิวเช่นข้อมูลเดียวกันอาจจะแสดงผลออกมาในรูปกราฟ รูปต้นไม้ หรือแบบฟอร์มก็ได้
3. Controller ทำหน้าที่เป็นตัวกลั่นกรองอินพุต และควบคุมเส้นทางการทำงาน (Workflow Management) ตัวอย่างของ Controller เช่นการรับข้อมูลเข้าอาจจะผ่านทาง Mouse หรือ Keyboard ก็ได้ ในกรณีของเว็บแอพพลิเคชันตัวออบเจกต์ Controller จะทำหน้าที่จัดการเส้นทางของ Page และแปลงพารามิเตอร์ที่รับเข้ามาให้อยู่ในสภาพพร้อมใช้งาน
เราจะเห็นว่า MVC จะเกิดปัญหาเมื่อมาใช้งานกับเว็บแอพพลิเคชันคือ การแจ้งเหตุการณ์เปลี่ยนแปลงจากโมเดลมาที่วิวไม่สามารถทำได้ง่ายนัก เนื่องจากโปรโตคอลของเว็บเป็นแบบ Connectionless คือเมื่อเซิร์ฟเวอร์ Response กลับไปให้ไคลเอ็นต์แล้วจะไม่มีการเชื่อมต่อค้างไว้ ดังนั้นเมื่อโมเดลบนฝั่งเซิร์ฟเวอร์มีการเปลี่ยนแปลงจึงไม่สามารถแจ้งกลับไปให้เบราเซอร์เปลี่ยนข้อมูลที่กำลังแสดงผลอยู่ได้
วิธีการที่ยอมรับได้สำหรับการอัพเดตวิว มีอยู่ 3 วิธีคือ
1. Client Pull หน้าเว็บจะอัพเดตตามข้อมูลในโมเดลเมื่อผู้ใช้กดปุ่ม Refresh เพื่อสั่งโหลดหน้าเว็บใหม่อีกครั้ง
2. Periordic Client Pull หน้าเว็บจะถูก Refresh อัตโนมัติทุกๆช่วงเวลาหนึ่งที่กำหนดไว้
3. Server Push การเชื่อมต่อถูกล็อคค้างไว้ตั้งแต่ครั้งแรกที่ผู้ใช้ได้รีเควสต์ไปที่เซิร์ฟเวอร์ แล้วหลังจากนั้นเซิร์ฟเวอร์จะส่งข้อมูลเปลี่ยนแปลงมาให้เบราเซอร์ทุกครั้งที่มีการเปลี่ยนแปลงเกิดขึ้นกับโมเดล
5.1 MVC กับ Jakarta Struts
สำหรับ Jakarta Struts ได้ถูกออกแบบมาให้ใกล้เคียงกับ MVC มากที่สุด โดยมีออบเจกต์ที่ประกอบกันอยู่เฟรมเวิร์คหลายตัว ดังนี้
1. เมื่อผู้ใช้รีเควสต์เข้ามาโดยระบุ url ให้ลงท้ายด้วยคำว่า .do (โปรแกรมเมอร์อาจจะกำหนดให้เป็นคำอื่นได้โดยแก้ไขไฟล์ web.xml) Servlet Container จะไปเรียกใช้งาน ActionServlet โดยส่ง ServletRequest และ ServletResponse ไปให้
2. ActionServlet ทำหน้าที่เป็น MVC Controller โดยโหลดค่าคอนฟิกเกอเรชันจากไฟล์แล้วส่งต่อให้กับ RequestProcessor
3. RequestProcessor ทำหน้าที่เป็น MVC Controller โดยตรวจสอบว่าจะเรียกใช้ออบเจกต์ Action ตัวไหน ออบเจกต์ RequestProcessor จะช่วยดึงค่าพารามิเตอร์จากไคลเอ็นต์มาใส่เป็น Property ให้กับตัวออบเจกต์ ActionForm แล้วส่งออบเจกต์ ActionForm ให้กับ Action นำไปใช้งานต่อ
4. Action ทำหน้าที่เป็นออบเจกต์ที่เก็บกระบวนการ เป็นส่วนหนึ่งของ MVC Controller โดย Action จะนำข้อมูลใน ActionForm มาตรวจสอบและสั่งให้ Business Component ทำงานต่อให้
5. Business Component เป็นออบเจกต์ที่ทำงานให้จริงๆ และทำงานตามระบบงานกับข้อมูลที่อยู่ในระบบงาน ดังนั้น Business Component จะตรงกับ MVC Model ส่วนใหญ่แล้ว Business Component จะถูกเขียนขึ้นเป็น Java Bean หรือ Enterprise JavaBeans ที่เข้าถึงข้อมูลในฐานข้อมูล (บางครั้งถูกเรียกว่า DAO – Data Access Object)
6. หลังจาก Action ทำงานเสร็จแล้วจะนำข้อมูลใส่ใน ActionForm ดังนั้น ActionForm จะเป็นส่วนหนึ่งของ MVC View
7. RequestProcessor จะตรวจดูออบเจกต์ ActionForward ที่ส่งกลับมาจาก Action ว่าต้องการให้นำข้อมูลไปแสดงผลที่หน้าไหน แล้วจัดการส่งต่อไปที่หน้านั้นโดยวิธี redirect หรือ forward
8. JSP ทำหน้าที่แสดงผล ดังนั้นเป็น MVC View และภายในจะประกอบด้วย Tag Libraries ที่เป็นของ Jakarta Struts เอง
9. Tag Libraries ถูกใช้ภายใน JSP เพื่อดึงค่าจาก ActionForm ขึ้นมาแสดงผลบนหน้าเว็บ ดังนั้น Tag Libraries เป็นส่วนหนึ่งของ MVC View ด้วย
ตาราง 1-8 สรุปชิ้นส่วนที่สำคัญใน Jakarta Struts แยกตามประเภท MVC
คำถามท้ายบท
1. ข้อใดต่อไปนี้กล่าวถูกต้องเกี่ยวกับ Servlet
a. เราสามารถสร้าง Servlet ได้โดยการสร้างคลาสสืบทอดต่อจาก Servlet
b. หลังจากสร้าง Servlet แล้วเราต้องสั่ง new ออบเจกต์ของคลาส Servlet นั้นด้วยจึงจะใช้งานได้
c. ทุกครั้งที่มีรีเควสต์เข้ามาที่ Servlet ตัว Servlet Container จะเรียกใช้เมธอด service() ของ Servlet ตัวนั้น
d. ออบเจกต์ Servlet จะถูกสร้างขึ้นทุกครั้งเมื่อมีรีเควสต์เข้ามา
2. ข้อใดต่อไปนี้กล่าวถูกต้องเกี่ยวกับ JSP
a. โปรแกรมเมอร์ไม่สามารถกำหนดให้โหลด JSP ขึ้นก่อนได้ (load on startup) แต่สามารถกำหนด load on startup ให้กับ Servlet ได้โดยแก้ไขค่าคอนฟิกเกอเรชันที่ไฟล์ web.xml
b. โปรแกรมเมอร์ไม่สามารถประกาศเมธอดไว้ภายในไฟล์ JSP ได้
c. โปรแกรมเมอร์ไม่สามารถกำหนดให้ JSP สืบทอดต่อจาก Servlet ได้
d. JSP จะต้องถูกเปลี่ยนเป็น Servlet โดยผ่านกระบวนการ Page Compilation
3. จงจับคู่ระหว่างความต้องการกับ Implicit Object ที่ตรงกัน
a. out 1. ต้องการเก็บข้อมูลค้างไว้ชั่วคราว และข้อมูลนี้ไม่หายไปเมื่อ Response กลับไปที่ไคลเอ็นต์แล้ว b. request 2. ต้องการแสดงรายการข้อผิดพลาดที่เกิดขึ้นกับระบบงาน c. session 3. ต้องการสร้างออบเจกต์ขึ้นเพียงตัวเดียวแต่ใช้งานตลอดทั้งระบบงาน d. application 4. ต้องการส่งต่อการทำงานไปให้กับหน้าอื่นด้วยวิธี redirect e. exception 5. ต้องการส่งข้อมูลไปให้หน้าอื่นด้วยวิธี forward d. response 6. ต้องการแสดงผลข้อมูล a. out 1. javax.servlet.ServletRequest b. request 2. javax.servlet.http.HttpSession c. session 3. javax.servlet.jsp.PageContext d. pageContext 4. javax.servlet.ServletContext e. application 5. javax.servlet.ServletConfig f. config 7. java.lang.Throwable g. exception 8. javax.servlet.jsp.JspWriter
5. จงจับคู่ระหว่าง Tag กับลักษณะของ Tag ที่ปรากฏ
a. Tag 1. b. BodyTag 2.
c. IterationTag 3. a. SKIP_BODY 1. doStartTag b. EVAL_BODY 2. doEndTag c. EVAL_BODY_INCLUDE 3. doInitBody d. EVAL_BODY_AGAIN 4. doAfterBody e. EVAL_BODY_BUFFERED 5. setBodyContent f. EVAL_PAGE 6. setPageContext g. SKIP_PAGE 7. release b. Declaration 2. c. Scriptlet 3. d. Expression 4. e. comment 5.
a. JSP Model 1 ใช้แต่ไฟล์ JSP อย่างเดียว
b. JSP Model 1 และ JSP Model 2 เหมือนกันเพียงแต่ใน Model 2 เปลี่ยนจากการใช้ JSP รับรีเควสต์มาใช้เป็น Servlet รับรีเควสต์แทน
c. JSP Model 1 ระบุให้ action ของแท็ก form ใน HTML เป็นไฟล์ JSP ที่จะรับรีเควสต์
d. JSP Model 2 ระบุให้ action ของแท็ก form ใน HTML เป็น Controller Servlet ที่จะรับรีเควสต์a. Employee 1. Model b. EmployeeTable 2. View c. EmployeeForm 3. Controller d. EmployeeEventListener e. EmployeeServlet
10. จงจับคู่ชิ้นส่วนใน Jakarta Struts กับประเภทของ MVC
a. HTML Tag Libraries 1. Model b. Action 2. View c. ActionServlet 3. Controller d. RequestProcessor e. ActionForward f. ActionForm g. JSP ที่มีใช้งาน Tag Lib







































