Thursday, November 6, 2008

JAKARTA STRUTS FRAMEWORK (ตอนที่ 4)

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


Image


ซอร์สโค้ด 1-13 ไฟล์ employee_search_form.jsp


Image


ซอร์สโค้ด 1-14 ไฟล์ employee_search.jsp


Image


ซอร์สโค้ด 1-15 ไฟล์ employee_search_result.jsp


Image


ให้สังเกตว่าวิธีของ JSP Model 1 จะใช้งาน JSP ล้วนๆไม่ได้มีการใช้งาน Servlet ร่วมด้วยเลย ซึ่งก็มีทั้งข้อดีและข้อเสีย ข้อดีคือ ถ้าแอพพลิเคชันไม่ค่อยซับซ้อนเท่าไรนัก การใช้วิธีนี้จะเข้าใจง่ายและไม่ต้องเสียเวลาเรียนรู้นาน โปรแกรมเมอร์ก็สามารถใช้งานได้ แต่ข้อเสียก็คือเมื่อระบบงานใหญ่ขึ้น มีจำนวนหน้าเว็บมากขึ้น การจะติดตามว่าหน้าเว็บไหนส่งต่อไปที่หน้าไหนทำได้ลำบากมาก เนื่องจากหน้าเว็บแต่ละหน้าอาจจะสั่ง redirect หรือ forward ไปให้กับหน้าไหนก็ได้
ข้อเสียอีกอย่างหนึ่งของวิธีนี้ก็คือ เมื่อมีงานบางอย่างที่ต้องทำทุกครั้งก่อนที่เข้าไปรันหน้าเว็บจะต้องแก้ไขไฟล์ JSP ทุกไฟล์ ตัวอย่างของงานประเภทนี้เช่น การตรวจสอบระดับสิทธิ์ของผู้ใช้ ซึ่งต้องตรวจสอบก่อนเข้าใช้ในทุกๆหน้า ถ้าเราใช้ Model 1 เราจะต้องเพิ่มกระบวนการตรวจสอบตรงนี้เข้าไปในไฟล์ JSP ทุกไฟล์ ซึ่งเป็นงานที่ลำบากและเกิดข้อผิดพลาดได้ง่าย


4.2 JSP Model 2


Image


ตามภาพที่ 11 อธิบายวิธีของ 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


Image



Image

วิธีการของ Model 2 จะต้องปรับแต่งไฟล์ web.xml เพื่อกำหนดค่า url pattern ที่ตรงกับที่เราต้องการแล้วให้ Servlet Container มาเรียกใช้  Servlet ตัวที่เป็น Controller


ซอร์สโค้ด 1-17 ไฟล์ web.xml ที่กำหนด url pattern


Image


จากซอร์สโค้ด 1-17 ให้สังเกตบรรทัดที่ 10 จะพบว่าเรากำหนดให้ url ที่รีเควสต์เข้ามาเป็นอะไรก็ตามที่ลงท้ายด้วยคำว่า .run ให้ไปรัน Servlet ชื่อ controller ที่คลาส ControllerServlet ด้วยวิธีนี้เราสามารถกำหนดให้ action ทุกๆ action ของ form ลงท้ายด้วยคำว่า .run เพื่อให้ส่งรีเควสต์มาที่ ControllerServlet ของเราก่อนแล้วค่อยให้ ControllerServlet แจกจ่ายงานออกไปอีกทีนึง


ซอร์สโค้ด 1-18 ไฟล์ employee_search_form2.jsp


Image


สำหรับ Jakarta Struts Framework จะใช้วิธีตาม Model 2 แต่จะเพิ่มเติม Action, ActionForm และ Tag Libraries เข้าไปเพื่อให้การทำงานสมบูรณ์ยิ่งขึ้น


5. MVC Design Pattern
จากตัวอย่างของ JSP Model 2 ที่กล่าวมาแล้วข้างต้น จะตรงกับคอนเซ็ปต์ของ MVC ที่ใช้ในการออกแบบระบบ GUI (Graphical User Interface) ทั่วไปในปัจจุบัน MVC เริ่มต้นใช้งานครั้งแรกในภาษา Smalltalk และปัจจุบันถูกนำไปประยุกต์ใช้ในอีกหลายๆ Framework เนื่องจากการออกแบบแบบ MVC จะทำให้ออบเจกต์ที่ทำงานในระบบมีหน้าที่ที่ชัดเจนยิ่งขึ้น


Image


จากภาพที่ 13 เราจะพบว่า MVC แบ่งออบเจกต์ออกเป็น 3 ประเภทคือ
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 มากที่สุด โดยมีออบเจกต์ที่ประกอบกันอยู่เฟรมเวิร์คหลายตัว ดังนี้


Image


จากภาพที่ 14 อธิบายขั้นตอนการทำงานของ Struts ได้ดังนี้
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


Image



คำถามท้ายบท
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.  ต้องการแสดงผลข้อมูล

4.     จงจับคู่ระหว่างชนิดข้อมูลกับ Implicit Object ที่ตรงกัน

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. 
     
1234
      
Sorapong
 

c. IterationTag
3. 

6.     จงจับคู่ระหว่างค่าคงที่และเมธอดที่สามารถส่งคืนค่าคงที่นั้นออกมาได้

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

7.     จงจับคู่ชื่อของ JSP Element กับแท็ก
b. Declaration
2.  
c. Scriptlet
3.  
d. Expression
4.  
e. comment
5.  

8.     ข้อใดกล่าวผิดเกี่ยวกับ JSP Model 1 และ Model 2
                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 ที่จะรับรีเควสต์

9.     จงแยกประเภทของออบเจกต์ตาม MVC

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
 


cradit : http://www.aczept.com

JAKARTA STRUTS FRAMEWORK (ตอนที่ 3)

3.5 วงจรชีวิตของ IterationTag


Image


1.     เมื่อ Servlet Container กำหนดค่าของแอททริบิวท์ในตัวออบเจกต์ Tag เสร็จแล้ว
2.     Servlet Container เรียกเมธอด setPageContext เพื่อกำหนดสภาวะแวดล้อมที่ Tag นั้นวางอยู่ในไฟล์ JSP
3.     ในกรณีที่แท็กนี้วางซ้อนอยู่ในแท็กอื่นจะถือว่าแท็กที่คลุมอยู่เป็น parent ตัว Container จะเรียกเมธอด setParent ด้วย
4.     หลังจากเสร็จ INIT PROTOCOL จะเรียกใช้เมธอด doStartTag
5.     หลังจากเสร็จ doStartTag จะตรวจดูว่าได้ค่าคืนมาเป็นอะไร ถ้าคืนค่ามาเป็น EVAL_BODY_INCLUDE จะเข้าไปรันแท็กย่อยๆเป็น Body ของแท็กนี้ต่อไป
6.     หลังจากรันผ่านบริเวณ Body แล้ว Servlet Container จะเรียกใช้เมธอด doAfterBody
7.     ตรวจสอบดูว่าค่าส่งคืนจากเมธอด doAfterBody เป็นอะไร ถ้าได้ค่าเป็น EVAL_BODY_AGAIN จะเริ่มต้นรันในส่วนของ Body ใหม่อีกครั้ง
8.     ถ้าได้ค่าคืนจากเมธอด doStartTag หรือ doAfterBody เป็น SKIP_BODY จะไปเรียกเมธอด doEndTag 
9.     เสร็จจาก doEndTag แล้วจะเรียกเมธอด release เพื่อเคลียร์ค่าแอททริบิวท์ เตรียมออบเจกต์ไว้ใช้ในครั้งต่อไป


ตัวอย่าง 5 แท็ก for ที่ทำงานเป็นวงรอบ
ซอร์สโค้ด 1-8 ไฟล์ ForTag.jsp


Image


จากซอร์สโค้ด 1-8 อธิบายได้ว่า
บรรทัดที่ 3                  ใช้ Directive taglib เพื่อให้ Servlet Container รู้ว่าเราจะใช้แท็กจาก uri ที่ชื่อ /iteration และทุกแท็กที่ขึ้นต้นด้วยสตริง logic: ให้ไปดูที่ uri นี้
บรรทัดที่ 11                เรียกใช้งานแท็ก for โดยให้แอททริบิวท์ count มีค่าเป็น 10
บรรทัดที่ 12                เรียกใช้งานแท็ก hello (ของเดิมดูจากในซอร์สโค้ด 1-5) 


ซอร์สโค้ด 1-9 ไฟล์ ForTag.java ทำหน้าที่เป็น Tag Handler Class


Image


จากซอร์สโค้ด 1-9 อธิบายได้ว่า
บรรทัดที่ 6                  สร้างคลาส ForTag สืบทอดจากคลาส TagSupport(ดูโครงสร้างคลาส TagSupport จากรูปภาพ 2
บรรทัดที่ 7                  กำหนดตัวแปร count สำหรับเก็บค่าแอททริบิวท์ count และใช้กำหนดจำนวนรอบที่จะทำงาน
บรรทัดที่ 8                  กำหนดตัวแปร i ใช้นับจำนวนรอบที่ได้ทำไปแล้ว
บรรทัดที่ 10-12          เตรียมเมธอด setCount สำหรับแอททริบิวท์ count ให้สังเกตว่าเราไม่จำเป็นต้องให้แอททริบิวท์มีชนิดข้อมูลเป็น String เท่านั้นในกรณีที่กำหนดให้เป็น int ตัว Container จะแปลงสตริงให้เป็น int เอง
บรรทัดที่ 14-17          Override เมธอด doStartTag ให้เริ่มต้นเข้าสู่แท็ก มีค่า i เริ่มต้นเป็น 0 สำหรับค่า count จะได้รับมาเองโดย Container จะเรียกเมธอด setCount พร้อมกับส่งค่าแอททริบิวท์ที่ให้ไว้ที่หน้าเว็บเข้ามาให้
                                    ส่งคือค่าเป็น EVAL_BODY_INCLUDE เพื่อบอกให้ Container ทำ Body ด้วย
บรรทัดที่ 19                หลังจากทำงานใน Body เสร็จแล้วจะมาเรียกที่เมธอดนี้
บรรทัดที่ 20                เพิ่มค่า i เพื่อนับจำนวนรอบที่ทำงานเพิ่มขึ้นอีกหนึ่ง แล้วตรวจสอบว่าจำนวนรอบที่ทำงานยังคงน้อยกว่า count หรือไม่ ถ้ายังน้อยกว่าให้ทำต่อไปอีก โดยคืนค่าเป็น EVAL_BODY_AGAIN แต่ถ้าครบตามจำนวนรอบที่ count แล้วให้หยุดทำโดยคืนค่าเป็น SKIP_BODY
บรรทัดที่ 24                เมื่อเสร็จการทำงานที่แท็กนี้ ให้รีเซ็ตค่า i และ count กลับเป็น 0 เพื่อเตรียมไว้ทำครั้งต่อไป


ซอร์สโค้ด 1-10 ไฟล์ for.tld แบบที่มีการระบุแอททริบิวท์ด้วย


Image


จากซอร์สโค้ด 1-10 อธิบายได้ว่า
บรรทัดที่ 13                กำหนดให้ Page Programmer ใช้งานแท็กชื่อว่า for
บรรทัดที่ 14                ให้สร้างออบเจกต์ Tag จากคลาส aczept.servlet.samples.ForTag
บรรทัดที่ 15                body-content สามารถมีค่าได้ 3 ค่าตามตารางที่ 1-6
บรรทัดที่ 17-21          กำหนดให้มีแอททริบิวท์หนึ่งตัวชื่อว่า count
บรรทัดที่ 19                ค่า required เป็น true หมายความว่าแอททริบิวท์นี้ต้องถูกกำหนดค่าไว้เสมอ
บรรทัดที่ 20                ค่า rtexprvalue(ย่อมาจาก request-time expression value) เป็น true หมายถึงแอททริบิวท์นี้สามารถรับค่าจาก Expression ได้ เช่นกำหนดค่า count=”<%=value %>” โดย value เป็นตัวแปรในหน้าเว็บ


ตารางที่ 1-6 ค่าที่ใส่ให้กับ body-content ในไฟล์ tld

Image

3.6 วงจรชีวิตของ BodyTag


 
Image


จากรูปภาพที่ 6 อธิบายการทำงานของแท็กที่มี Body ได้ดังนี้
1.     Servlet Container กำหนดค่าตั้งต้นให้กับออบเจกต์ Tag โดยเรียกเมธอด setter, setPageContext และ setParent
2.     เรียกเมธอด doStartTag แล้วตรวจสอบว่าค่าที่ได้คืนมาเป็นค่าอะไร ถ้าได้ค่าคืนมาเป็น EVAL_BODY_INCLUDE จะเข้าไปที่ทำงานใน Body ที่อยู่ภายใน แต่จะไม่เก็บเนื้อหาของ Body เอาไว้โดยไม่มีการเรียกเมธอด setBodyContent และ doInitBody
3.     ถ้าเมธอด doStartTag ส่งค่ากลับมาเป็น EVAL_BODY_BUFFERED จะสร้างออบเจกต์ BodyContent สำหรับเก็บเนื้อหา Body ไว้ด้วยแล้วส่งออบเจกต์นี้มาให้โดยเรียกใช้เมธอด setBodyContent หลังจากนั้นเรียกใช้เมธอด doInitBody ก่อนที่จะเข้าไปรันใน Body
4.     เข้าในรันใน Body จนเสร็จแล้วเรียกใช้เมธอด doAfterBody ถ้าเมธอด doAfterBody ส่งค่าคืนมาเป็น EVAL_BODY_AGAIN จะทำใน Body ใหม่อีกครั้ง แต่ถ้าส่งคืนค่ามาเป็น SKIP_BODY จะไปเรียกใช้เมธอด doEndTag
5.     หลังจากเสร็จสิ้นการใช้งานแท็กครั้งนี้ Servlet Container จะเรียกใช้เมธอด release เพื่อให้รีเซ็ตค่าแอททริบิวท์เตรียมไว้สำหรับการเรียกใช้แท็กใน
ครั้งต่อไป


ตัวอย่าง 6 แท็ก reverse ที่ใช้กลับด้านสตริง


ซอร์สโค้ด 1-11 ไฟล์ ReverseTag.jsp


Image


เมื่อรันซอร์สโค้ด 1-11 แล้วจะได้ผลลัพธ์ปรากฏบนเบราเซอร์คล้ายดังนี้

Image


ซอร์สโค้ด 1-12 ไฟล์ ReverseTag.java(Tag Handler Class)

Image

จากซอร์สโค้ด 1-12 อธิบายได้ว่า
บรรทัดที่ 9                  ให้ส่งคืนค่าเป็น EVAL_BODY_BUFFERED เพื่อบอกให้ Servlet Container รู้ว่าต้องเก็บ BodyContent ไว้
บรรทัดที่ 12-22          Override เมธอด doEndTag เพื่อกลับด้านสตริง
บรรทัดที่ 13                เรียกเมธอด getBodyContent เพื่อดึงออบเจกต์ BodyContent ออกมาใช้งาน เมธอดนี้มีอยู่ในคลาสแม่อยู่แล้ว และตัวออบเจกต์ BodyContent เป็นตัวแทนของข้อมูลที่อยู่ตรงกลางของแท็กนี้
บรรทัดที่ 14                เรียกเมธอด getString จากตัวออบเจกต์ BodyContent จะได้สตริงที่เกิดขึ้นที่ตรงกลางแท็กออกมาแล้วนำไปเก็บไว้ใน StringBuffer ตัวแปรชื่อ str
บรรทัดที่ 15                ดึงออบเจกต์ out มาไว้สำหรับแสดงผล
บรรทัดที่ 17                เรียกใช้เมธอด reverse ของคลาส StringBuffer เพื่อกลับด้านสตริงแล้วเรียกเมธอด toString ให้คืนค่าสตริงที่กลับด้านเสร็จแล้วออกมา สตริงผลลัพธ์ที่ได้ให้แทรกเข้าไปในบัพเฟอร์หน้าเว็บเพื่อแสดงผล
 

4. JSP Model 1 และ Model 2
รูปแบบที่โปรแกรมเมอร์ทั่วๆไปนิยมนำไปสร้างเว็บแอพพลิเคชัน มีอยู่ 2 แบบ คือ Model 1 และ Model 2 แม้ว่าทั้งสองแบบนี้
จะไม่ได้ถูกกำหนดไว้ในมาตรฐานของ Servlet  และ JSP แต่ทั้งสองโมเดลนี้ก็เป็นที่นิยมเรียกกันในหมู่โปรแกรมเมอร์ 


4.1 JSP Model 1

Image

ตามภาพที่ 7 เราจะพบว่า Model 1 มีลักษณะการทำงาน ดังนี้
1.     ผู้ใช้รีเควสต์เข้ามาที่ไฟล์ jsp ไฟล์ใดไฟล์หนึ่งในเว็บแอพพลิเคชันของเรา ในไฟล์ jsp นี้จะเขียนโปรแกรมเพื่อดึงค่าพารามิเตอร์ออกมาโดยใช้คำสั่ง 
            String variable=request.getParameter(“ชื่อพารามิเตอร์”);
        แล้วนำค่าพารามิเตอร์ที่ได้ ไปดำเนินการตามวัตถุประสงค์ของระบบ
2.     ไฟล์ JSP #1 ที่รับอินพุตเข้ามาไม่ได้ทำงานเอง แต่สั่งให้ออบเจกต์บีน (Bean) ตัวอื่นที่อยู่ระบบทำงานให้พร้อมกับส่ง
พารามิเตอร์ไปให้กับบีนด้วย เมื่อบีนทำงานเสร็จแล้วจะได้ผลลัพธ์กลับมา ไฟล์ JSP #1 จะเป็นผู้เลือกว่าจะส่งผลลัพธ์นี้ไป
แสดงผลที่ไฟล์ jsp ไฟล์ไหน แล้วส่งไปแสดงผลที่ไฟล์นั้นโดยใช้วิธี redirect หรือวิธี forward ก็ได้ ความแตกต่างระหว่างวิธี
 redirect และวิธี forward ให้ดูจากตาราง 1-7
3.     ไฟล์ JSP #2 แสดงผลลัพธ์ที่รับมาจากไฟล์ JSP #1

 
ตาราง 1-7 ความแตกต่างระหว่าง redirect กับ forward
 
 
Image

 

Image


ตามภาพที่ 8 จะพบว่าการทำงานแบบ redirect มีลักษณะดังนี้
1.     เมื่อเว็บเบราเซอร์รีเควสต์ไปที่ 
http://mysite/Page1.jsp 
2.     เมื่อ Servlet Container รัน Page1 มาถึงบรรทัดที่สั่ง response.sendRedirect(“
http://mysite/Page2.jsp?p1=xyz”) 
จะหยุดการทำงานที่หน้าเว็บ แล้วส่งบัพเฟอร์หน้าเว็บนี้กลับมาให้กับเว็บเบราเซอร์ โดยที่ส่วนหัวของ HTTP Response มีระบุ
ฟิลด์ LOCATION เป็น 
http://mysite/Page2.jsp?p1=xyz ด้วย
3.     เมื่อเว็บเบราเซอร์รับ HTTP Response กลับมาจะพบว่ามีฟิลด์ LOCATION ระบุไว้อยู่ ตัวเว็บเบราเซอร์จะรู้ว่าหน้าที่ส่ง
ลงมานี้ไม่ต้องแสดงผล แต่ให้ไปรีเควสต์ที่ url ตามที่ระบุไว้ใน LOCATION เช่นนี้จะเหมือนกับเวลาที่เราพิมพ์ url เข้าไปที่
ช่องแอดเดรสของเบราเซอร์แล้วกดปุ่ม Enter เพื่อให้มันเบราซ์ให้
4.     Servlet Container ได้รับรีเควสต์และรันที่ Page2 เมื่อรันไปถึงบรรทัดที่สั่ง response.sendRedirect(…) ก็จะทำเช่น
เดียวกันกับข้อ 2 

 
เราจะเห็นว่าวิธี redirect นี้ เซิร์ฟเวอร์ต้อง Response กลับมาที่ไคลเอ็นต์ก่อนแล้วจึงปล่อยให้เป็นของหน้าที่ของเว็บเบราเซอร์ Request กลับขึ้นไปที่เซิร์ฟเวอร์อีกครั้ง ดังนั้นการรีเควสต์อีกครั้งที่เกิดขึ้นจะไม่ได้ใช้ออบเจกต์ Request ตัวเดียวกันกับ Request ครั้งในแรก ซึ่งถ้า Page1 อยากจะส่งข้อมูลมาให้ Page2 จะทำได้สองวิธีคือ ติดข้อมูลมาให้เป็น Query String โดยใช้วิธี Get เช่น Page2.jsp?p1=xyz&p2=abc หรืออีกวิธีโดยเก็บข้อมูลไว้ใน Session แล้วให้ Page2 ไปดึงข้อมูลจาก Session มาใช้งานเช่น Page1 สั่ง session.setAttribute(“p1”, “xyz”) แล้วที่ Page2 ก็ดึงข้อมูลกลับมาใช้โดยสั่ง session.getAttribute(“p1”)

 
Image


ตามภาพที่ 9 จะพบว่าการส่งต่องานแบบ forward มีลักษณะดังนี้
1.     เมื่อเว็บเบราเซอร์รีเควสต์ไปที่ 
http://mysite/Page1.jsp Servlet Container สร้างออบเจกต์ SerlvetRequest 
แล้วส่งให้กับ Page1.jsp แล้วรันไปเรื่อยๆ
2.     เมื่อรันมาถึงบรรทัดที่สั่ง จะไม่ทำงานต่อลงไปในส่วนที่เหลือด้านล่างไฟล์ 
แต่จะไปรันไฟล์ Page2.jsp พร้อมกับนำออบเจกต์ ServletRequest จาก Page1.jsp ส่งต่อให้กับ Page2.jsp ดังนั้นถ้า 
Page1.jsp ต้องการส่งข้อมูลอะไรให้กับ Page2.jsp ก็สามารถทำได้โดยกำหนดเป็นแอททริบิวท์ใส่ไว้ใน request เช่น 
Page1.jsp สั่ง request.setAttribute(“p1”, “xyz”) แล้วที่ Page2.jsp สามารถดึงค่าแอททริบิวท์มาใช้โดยสั่ง 
request.getAttribute(“p1”)
3.     เมื่อรัน Page2.jsp มาถึงบรรทัด จะไม่ทำงานด้านล่างต่อ แต่จะไปรัน 
Page3.jsp พร้อมกับส่งออบเจกต์ ServletRequest ที่ใช้มาตั้งแต่ Page1.jsp ไปให้กับ Page3.jsp ใช้งานต่อ
4.     ที่ Page3.jsp รันไปจนกระทั่งจบไฟล์ ไม่มีคำสั่งให้ forward ไปที่ไหนต่อ ก็จะส่ง HTTP Response กับไปแสดงผล
ที่ไคลเอ็นต์เบราเซอร์


เราจะเห็นว่าระหว่าง forward จะทำงานอยู่ที่ Servlet Container ตลอดโดยยังไม่ส่งกลับมาที่ไคลเอ็นต์ รวมทั้งใช้ออบเจกต์ 
Servlet Request ร่วมกันในทุกๆหน้าที่มีการ forward ถึงด้วย เราเรียกทุกหน้าที่ใช้ ServletRequest ร่วมกันนี้ว่ารันอยู่ใน 
request scope และเรียกแอททริบิวท์ที่ใส่เข้าไปใน ServletRequest ว่าเป็น request scope attributes
ไฟล์ ForTag.java ทำหน้าที่เป็น Tag Handler Class

cradit : http://www.aczept.com

JAKARTA STRUTS FRAMEWORK (ตอนที่ 2)

3.3 วงจรชีวิตของออบเจกต์ Tag อย่างง่าย


Image 

Servlet Container จะควบคุมการสร้างและการเรียกใช้ตัวออบเจกต์ Tag เองโดยอัตโนมัติ ตัวอย่างของแท็กอย่างง่ายที่ไม่มี Body เช่น

                       

จะมีขั้นตอนการทำงาน ดังต่อไปนี้
1.     เมื่อ Servlet Container รันมาถึงบรรทัดที่ใช้งานแท็ก Serlvet Container จะไปดึงออบเจกต์ Tag ที่ทำหน้าที่เป็น Handler ของแท็กนี้ออกมาจากพูล(หรือในกรณีเป็นการเรียกใช้งานครั้ง Servlet Container จะสร้างออบเจกต์ Tag ตัวนี้ขึ้นใหม่)
2.     Servlet Container สั่ง setPageContext เพื่อกำหนดสภาวะแวดล้อมขณะรันให้กับออบเจกต์ Tag นำไปใช้งาน ตัวออบเจกต์ pageContext ที่ Container มอบให้กับ Tag จะทำให้แท็กสามารถใช้งาน Implicit Object ต่างๆได้เหมือนกับการโปรแกรมที่หน้าเว็บ
3.     Servlet Container กำหนดค่าแอททริบิวท์ให้กับออบเจกต์ Tag โดยเรียกเมธอด setter ที่มีชื่อสอดคล้องกับชื่อแอททริบิวท์ที่ระบุ เช่นจากตัวอย่างนี้ Servlet Container จะเรียกเมธอด setMonth(“1”) และเรียกเมธอด setYear(“2003”) เป็นต้น(การค้นหาชื่อเมธอด set และ get จะเป็นไปตามกฏการตั้งชื่อ Property ของ Java Bean โดยชื่อเมธอดจะนำหน้าด้วยคำว่า set หรือ get แล้วตามด้วยชื่อ Property)
4.     Servlet Container เรียกเมธอด doStartTag และถ้าเมธอด doStartTag ส่งคืนค่ากลับมาเป็น SKIP_BODY ตัว Container จะไม่ประมวลผลเนื้อหาที่อยู่ตรงกลางแท็ก
5.     Servlet Container เรียกเมธอด doEndTag และถ้าเมธอด doEndTag ส่งคืนค่ากลับมาเป็น EVAL_PAGE ตัว Container จะรู้ว่าได้รับอนุญาตให้รันหน้าเว็บนั้นในส่วนท้ายต่อลงไป แต่ถ้าคืนค่ากลับมาเป็น SKIP_PAGE ตัว Container จะรู้ว่าไม่ต้องรันส่วนท้ายของหน้าเว็บที่ต่อจากแท็กนี้ต่อไปอีกแล้ว
6.     เมื่อจะหลุดพ้นออกจากแท็ก Servlet Container จะเรียกเมธอด release เพื่ออนุญาตให้ออบเจกต์เคลียร์ค่าแอททริบิวท์ที่เก็บไว้ ก่อนที่จะถูกเรียกใช้ในครั้งถัดไป


ตัวอย่าง 4 แท็กที่ไม่มี Body
ซอร์สโค้ด 1-4 ไฟล์ HelloWorldTag.java(Tag Handler)

Image

จากซอร์สโค้ด 1-4 อธิบายได้ว่า
บรรทัดที่ 6                  สร้างคลาส HelloWorldTag สืบทอดต่อจาก TagSupport เพื่อเตรียมสร้างแท็กแบบที่ไม่มี Body
บรรทัดที่ 7                  Override เมธอด doEndTag เพื่อใส่การทำงานที่ต้องการเข้าไปให้
บรรทัดที่ 9                  ดึงบัพเฟอร์หน้าเว็บออกมาจากตัวแปร pageContext ตัวแปร pageContext นี้มีให้ใช้เนื่องจากคลาสแม่ TagSupport ได้จัดเตรียมไว้ให้เรียบร้อยแล้ว เมธอด getOut จะคืนค่ากลับมาเป็นชนิด JspWriter และเป็นออบเจกต์ตัวเดียวกันกับ Implicit Object ที่ชื่อ out ที่ถูกใช้ในไฟล์ JSP
บรรทัดที่ 10                แทรกคำว่า Hello World เข้าไปในบัพเฟอร์หน้าเว็บ เมื่อจบแท็กนี้แล้วบัพเฟอร์ของแท็กจะถูกรวมเข้ากับบัพเฟอร์ใหญ่ของหน้าเว็บแล้วคำว่า Hello World จะไปปรากฏเป็นส่วนหนึ่งของ HTML
บรรทัดที่ 14                ส่งคืนค่าเป็น EVAL_PAGE บอกให้ Servlet Container ทำงานส่วนที่เหลือในหน้าเว็บต่อไป


ซอร์สโค้ด 1-5 ไฟล์ HelloWorldTag.jsp (เรียกใช้งาน Custom Tag)

Image
จากซอร์สโค้ด 1-5 อธิบายได้ว่า
บรรทัดที่ 2                  ให้ Servlet Container รู้ว่าเมื่อพบแท็กใดก็ตามที่ขึ้นต้นด้วย say: ให้เข้าไปหาตำแหน่งของไฟล์ TLD(Tag Library Definition) จาก uri ที่ชื่อว่า /location ในไฟล์ web.xml
บรรทัดที่ 10                เมื่อรันมาถึงบรรทัดนี้ Servlet Container จะพบแท็ก hello ขึ้นต้นด้วย prefix ว่า say: แล้วจะเข้าไปค้นในไฟล์ web.xml จนกระทั่งพบว่า uri ที่ชื่อว่า /location แม็พอยู่กับไฟล์ hello.tld(ไฟล์ TLD นี้จะกล่าวถึงต่อไป) 
Servlet Container จะดูในไฟล์ hello.tld และพบว่าต้องไปเรียกใช้ออบเจกต์จากคลาสชื่อ HelloWorldTag หลังจากนั้นจะเรียกเมธอด setPageContext, doStartTag, doEndTag และ release ตามลำดับ


3.4 การติดตั้ง Tag Libraries
เมื่อโปรแกรมเมอร์ได้รับ Tag Libraries มาและต้องการนำเข้ามาใช้ในเว็บแอพพลิเคชันของตัวเอง จะต้องทำตามขั้นตอนต่อไปนี้
1.     ตรวจสอบดูว่าในไลบรารีที่ได้รับมามีไฟล์ tld แนบมาด้วย เนื่องจากไฟล์ tld จะเก็บข้อมูลสำคัญของ Tag Libraries และ Servlet Container จำเป็นต้องใช้ข้อมูลจากในไฟล์ tld เพื่อหาว่าจะเรียกใช้ออบเจกต์จากคลาสไหนเมื่อพบกับแท็กในหน้าเว็บ


ซอร์สโค้ด 1-6 ตัวอย่างไฟล์ tld ที่ใช้สำหรับจับคู่แท็ก hello กับคลาส HelloWorldTag

Image
2.     ถ้าได้รับโค้ดมาเป็นไฟล์ class ให้นำไปวางไว้ในไดเร็คทอรี classes ภายใต้ไดเร็คทอรี WEB-INF ในเว็บแอพพลิเคชัน หรือถ้าได้รับโค้ดแพ็คมาเป็นไฟล์ jar ให้นำไฟล์ jar นั้นไปวางไว้ในไดเร็คทอรี lib ภายใต้ไดเร็คทอรี WEB-INF ในเว็บแอพพลิเคชัน
3.     นำไฟล์ tld ที่แนบมา วางไว้ภายใต้ไดเร็คทอรีใดก็ได้ภายใต้ไดเร็คทอรี WEB-INF ชื่อไดเร็คทอรีที่ใช้กันทั่วไปสำหรับวางไฟล์ tld คือ tlds
4.     เพิ่มการคอนฟิก Tag Libraries ใส่เข้าไปในไฟล์ web.xml ที่อยู่ภายใต้ไดเร็คทอรี WEB-INF ตัวอย่างของไฟล์ web.xml ที่ใช้กับ HelloWorldTag ตามตัวอย่างข้างต้น ดูได้ที่ซอร์สโค้ด 1-6 ต่อไปนี้


ซอร์สโค้ด 1-7 ตัวอย่างไฟล์ web.xml ที่ระบุตำแหน่งที่อยู่ของไฟล์ tld และกำหนด uri ที่เข้าคู่กัน

Image

5.     นำแท็กไปใช้งานในไฟล์ JSP โดยเขียน Directive taglib ระบุ uri ที่มีอยู่ในไฟล์ web.xml และกำหนด prefix ขึ้นใช้เองตามความพอใจของโปรแกรมเมอร์

Image

ในรูปภาพที่ 4 สามารถอธิบายแต่ละขั้นตอนได้ ดังนี้
1.     เมื่อ Servlet Container รันมาพบแท็ก abc:mytag
2.     นำ prefix ชื่อ abc ไปตรวจดูที่ Directive taglib ในส่วนหัวของไฟล์ JSP นั้น
3.     พบว่า prefix ชื่อ abc จับคู่อยู่กับ uri ชื่อ /xyz
4.     เข้าไปค้น uri ชื่อ /xyz จากในไฟล์ web.xml ภายใต้ไดเร็คทอรี WEB-INF ภายในเว็บแอพพลิเคชัน
5.     พบว่า uri ชื่อ /xyz เป็นไฟล์ชื่อ mylib.tld วางอยู่ในไดเร็คทอรี WEB-INF
6.     เข้าไปตรวจสอบดูในไฟล์ mylib.tld หาแท็กที่ชื่อว่า mytag
7.     พบว่าแท็กชื่อ mytag จับคู่อยู่กับคลาสชื่อ hello.HelloTag จึงไปเรียกใช้ออบเจกต์ Tag ที่ถูกสร้างจากคลาส hello.HelloTag โดย Servlet Container จะสร้างออบเจกต์ตัวนี้ขึ้นใหม่ในครั้งแรกที่รัน แล้วหลังจากนั้นจะ reuse ใช้ไปเรื่อยๆ
8.     เข้าไปเรียกเมธอด ตามขั้นตอนของการรันออบเจกต์ Tag เช่นในกรณีที่เป็นแท็กอย่างง่ายที่ไม่มี Body จะเรียกใช้เมธอด setPageContext, doStartTag, doEndTag และ release ตามลำดับ
9.     จบการทำงานและทำส่วนต่อไปในหน้าเว็บนั้น


ให้สังเกตว่าขั้นตอนการใช้งาน Tag Libraries ค่อนข้างยุ่งยากหลายขั้นตอน แต่มีข้อดีคือการทำงานร่วมกันระหว่างบุคคลหลายๆบทบาทจะทำได้สะดวกขึ้น เช่น 
1.     Tag Programmer พัฒนา Tag Libraries โดยสร้างคลาสที่เป็น Tag Handler และเขียนไฟล์ tld กำกับไว้ แล้วจ่ายแจกไลบรารีของตนให้คนอื่นนำไปใช้งาน
2.     Programmer Leader นำ Tag Libraries มาใช้ในการพัฒนาเว็บแอพพลิเคชันโดยกำหนดตำแหน่งที่วางไฟล์ tld และ uri ที่จะใช้งานร่วมกันในทีมงานพัฒนาเว็บ
3.     Page Programmer นำ Tag ที่ Programmer Leader บอกว่าสามารถใช้งานได้ มาใช้ในหน้าเว็บโดยเขียน Directive taglib และระบุ uri ให้ตรงกับที่ Programmer Leader กำหนดไว้ในไฟล์ web.xml โปรแกรมเมอร์จะตั้งชื่อ prefix ขึ้นใช้เองในไฟล์ JSP ที่เค้ากำลังโปรแกรมอยู่
โดยไม่ขึ้นอยู่กับ prefix ของโปรแกรมเมอร์คนอื่น

JAKARTA STRUTS FRAMEWORK (ตอนที่ 1)

ก่อนที่จะมี Java Servlet ได้มีการพัฒนาเว็บแอพพลิเคชันด้วย CGI (Common Gateway Interface) ซึ่งเป็นวิธีที่อนุญาตให้ HTTP Request ที่เข้ามาที่พอร์ต 80 ซึ่งเป็น Listenning Port ปกติของ Web Server สามารถส่งต่อไปให้กับโปรแกรมอะไรก็ได้ที่สามารถรันได้ที่ฝั่งเซิร์ฟเวอร์ โดยตัว CGI จะไปเปิดโปรแกรมที่เป็นกำหนดไว้ให้รันขึ้นมาเป็นโปรเซสใหม่ แล้วส่ง HTTP Request เข้าไปให้กับโปรแกรมนั้นโดยผ่านทาง Standard Input (stdin) ตามปกติ

Image 

ในระยะแรกมักนิยมเขียนโปรแกรมทางฝั่งเซิร์ฟเวอร์ด้วยภาษา C เนื่องจากง่ายต่อการรับอินพุตจาก Standard Input และส่งผลลัพธ์ออกไปทาง Standard Output ผลลัพธ์ที่ออกจากโปรแกรมจะถูก CGI เปลี่ยนทิศทางกลับไปให้ไคลเอ็นต์
วิธีการของ CGI ได้รับความนิยมอยู่ระยะหนึ่งเนื่องจากได้รับการหนุนเสริมจากภาษา PERL ที่ช่วยให้ง่ายต่อการประมวลสตริง การตัดต่อและประกอบสตริงที่เป็น HTTP Request และ Response ทำได้ง่ายกว่าการใช้ภาษา C มาก แต่อย่างไรก็ตาม CGI และ PERL ยังมีข้อเสียในด้านประสิทธิภาพอยู่ ก็คือ CGI จะรัน PERL ทุกครั้งที่มี HTTP Request เข้ามา และการรันนี้ทำในระดับของ Process ซึ่งหนึ่ง Process ต้องมีทั้งส่วน Code, Data และ Stack ทำให้เปลืองทรัพยากรของระบบมาก ในกรณีที่มี HTTP Request เข้ามามากระดับหนึ่งจะทำให้เครื่องเซิร์ฟเวอร์ไม่สามารถให้บริการต่อไปได้

1. แนะนำ Java Servlet
Servlet ได้รับการปรับปรุงจาก CGI และ PERL ในหลายๆเรื่อง เช่นเรื่องของประสิทธิภาพ เนื่องจาก Servlet ทำงานในระดับ Thread และเป็นระดับที่เปลืองทรัพยากรน้อยกว่าระดับ Process ทำให้เครื่องเซิร์ฟเวอร์ที่ใช้ Servlet สามารถให้บริการไคลเอ็นต์ได้จำนวนมากกว่าเครื่องที่ใช้ CGI และ PERL 

สิ่งที่เป็นประโยชน์อย่างยิ่งของ Servlet ก็คือ Servlet ยึดมั่นตามมาตรฐานของ API(Application Programming Interface) ที่กำหนดโดย Sun Microsystem ซึ่งมีผลให้ Servlet ที่พัฒนาขึ้นสามารถนำไปรันได้บน Servlet Container จากผลิตภัณฑ์ยี่ห้อใดก็ได้ ผู้ผลิตที่จำหน่าย Servlet Container ที่อิงตาม Servlet Specification จะรับรองว่าผลิตภัณฑ์ของเขาสามารถรัน Servlet ได้ถูกต้องตรงตามมาตรฐาน วิธีการแบบนี้เป็นผลจากความพยายามของ Sun Microsystem ที่จะทำให้ Java เป็นภาษาแบบ Vendor Independence ก็คือ โปรแกรมเมอร์ที่พัฒนาโปรแกรมด้วยภาษา Java สามารถเลือกตัว Container จากผู้ผลิตได้หลายๆราย โดยไม่ผูกติดกับผลิตภัณฑ์ยี่ห้อใดยี่ห้อหนึ่ง


Servlet Container เป็นโปรแกรมที่สร้างขึ้นมาเพื่อรัน Servlet โดย ผู้ผลิตที่มีความชำนาญทางด้านของ System-Level Programming จะเป็นผู้สร้าง Serlvet Container ขึ้นตามมาตรฐานของ Servlet Specification แล้วจำหน่ายจ่ายแจกให้โปรแกรมเมอร์ที่โปรแกรม Servlet สามารถนำมาใช้พัฒนาเว็บแอพพลิเคชันได้ ตัว Servlet Container บางตัวอาจจะทำหน้าที่เป็น Web Server อยู่ในตัวเองด้วย แต่สำหรับ Servlet Container บางตัวอาจจะเป็นแค่โปรแกรมที่ต้อง Plug-in เข้ากับ Web Server อื่นเพื่อให้สามารถใช้งานได้(ปกติแล้ว Web Server ทั่วๆไปอย่างเช่น IIS หรือ Apache Web Server จะไม่รู้จัก HTTP Request ที่ขอให้รัน Servlet หรือ JSP แต่จะรู้จักรีเควสต์ธรรมดาทั่วๆไปที่ขอไฟล์ html เท่านั้น)

ตารางที่ 1-1 รายชื่อ Serlvet Container ที่เป็นที่นิยมใช้อยู่ในปัจจุบัน

Image

ตัวอย่าง 1 HelloWorldServlet

ซอร์สโค้ด 1-1 HelloWorldServlet.java

Image

จากซอร์สโค้ด 1-1 อธิบายได้ว่า
 
บรรทัดที่ 3-5              อิมพอร์ตคลาสที่จำเป็นจากแพคเกจ javax.servlet และ javax.servlet.http
บรรทัดที่ 7                  สร้างคลาสใหม่ชื่อ HelloWorldServlet ให้สืบทอดต่อจาก HttpServlet
บรรทัดที่ 8                  สร้างเมธอด doGet โอเวอร์ไรด์เมธอด doGet ในคลาสแม่
บรรทัดที่ 10                กำหนดให้แสดงผลเป็น HTML และแสดงภาษาไทย
บรรทัดที่ 12-16          สร้างหน้าเว็บ HTML ให้มีคำว่า Hello World ปรากฏบนหน้าเว็บ
 
จากซอร์สโค้ด 1-1 เราจะเห็นว่าการเขียนโปรแกรม Servlet มีข้อเสียคือ
1.     ตกแต่งหน้าเว็บลำบาก เนื่องจากโค้ด HTML ถูกเขียนลงไปอยู่ใน ซอร์สโค้ด Java 
2.     ปกติคนที่ตกแต่งหน้าเว็บคือ Web Designer แต่คนที่เขียนโค้ดจาวาคือ Programmer แต่ใน Servlet โค้ด HTML ปนอยู่กับโค้ด Java ทำให้ Web Designer ไม่สามารถตกแต่งหน้าเว็บได้
3.     แก้ไขโปรแกรมลำบากเนื่องจากการทำงานจริงๆของโปรแกรมปะปนอยู่กับการแสดงผลด้วย HTML สตริง
4.     ไม่สามารถ Reuse(นำมาใช้ใหม่หลายๆครั้ง) ได้เนื่องจากโค้ดกระบวนการกับการแสดงผลปนกันอยู่
ปัจจุบัน Java Servlet ได้พัฒนา Specification มาถึงเวอรัชัน 2.3 และ Servlet Container ส่วนใหญ่ก็สนับสนุนการทำงานตามเวอร์ชันนี้แล้วด้วย

 

2. แนะนำ JavaServer Page
หลังจากมีการใช้งาน Servlet ไปได้ระยะหนึ่ง Sun Microsystem ได้เสนอให้ Servlet Container สนับสนุน JavaServer Page ด้วย วิธีการของ JavaServer Page จะให้โปรแกรมเมอร์สามารถแทรกโค้ด Java เข้าไปในซอร์สโค้ด HTML แล้วบันทึกไฟล์ไว้เป็นนามสกุล *.jsp แล้วนำไปรันใน Servlet Container

Servlet Container จะรู้จักไฟล์นามสกุล jsp และเมื่อมี HTTP Request มาจากไคลเอ็นต์มาที่ไฟล์ jsp Container จะนำซอร์สโค้ดของไฟล์ jsp มาสร้างเป็น Servlet เราเรียกขั้นตอนนี้ว่า Page Compilation เมื่อได้ Class ที่เป็น Servlet แล้ว Servlet Container ก็จะรัน Serlvet ตามปกติ กระบวนการ Page Compilation ดังกล่าวนี้จะทำกับไฟล์ jsp เพียงครั้งเดียวเท่านั้น เมื่อมี HTTP Request เข้ามาที่ไฟล์เดิมอีก Servlet Container จะไปรัน Servlet ที่คอมไพล์ไว้แล้วทันที
ใน JavaServer Page จะมีส่วนประกอบหลัก 5 ส่วนคือ 

 
ตารางที่ 1-2 ส่วนประกอบของการเขียนโปรแกรมด้วย JavaServer Page
 
Image

ซอร์สโค้ด
 1-2 HelloWorldJSP.jsp
 
Image

จากซอร์สโค้ด 1-2 อธิบายได้ว่า
บรรทัดที่ 1                  กำหนดให้แสดงผล HTML และใช้ตัวอักษรภาษาไทย
บรรทัดที่ 9                  ใช้ Expression แสดงผลคำว่า Hello World ภายในแท็ก h1 
ดังนั้นเราจะเห็น Hello World ปรากฏเป็นตัวเข้มหนาที่หน้าเว็บ


ตัวอย่าง 3 ไฟล์ Java Servlet ที่ได้จาก Page Compilation ของ Tomcat 4

ซอร์สโค้ด 1-3 ไฟล์ HelloWorldJSP$jsp.java ที่ได้จากการคอมไพล์ด้วย Tomcat 4


Image
Image
Image


 จากซอร์สโค้ด 1-3 อธิบายได้ว่า
บรรทัดที่ 44                Directive page contentType ที่เราเขียนที่ไฟล์ jsp ถูกเปลี่ยนเป็น response.setContent Type() ตามปกติของการเขียนโปรแกรม Java Servlet
บรรทัดที่ 48-51          เตรียม Implicit Object ให้ใช้งานที่หน้าเว็บ(ดูชื่อของ Implicit Object ที่ตาราง 1-3)
บรรทัดที่ 54                โค้ด HTML ที่เราเขียนในไฟล์ jsp ถูกเปลี่ยนให้กลายเป็นสแตติคสตริงธรรมดาที่เขียนออกไปที่แทรกเข้าไปในบัฟเฟอร์สำหรับแสดงผลด้วยคำสั่ง out.write()
 
ใน JavaServer Page จะกำหนดให้ Servlet Container ต้องจัดเตรียมออบเจกต์มาตรฐานไว้ให้โปรแกรมเมอร์สามารถเรียกใช้ได้เลยในโปรแกรมที่หน้าเว็บ เราเรียกออบเจกต์เหล่านี้ว่า Implicit Object ซึ่งโปรแกรมเมอร์จะไม่สามารถนำชื่อตัวแปรเหล่านี้ไปตั้งเป็นชื่อตัวแปรได้ ต่อไปนี้เป็นรายการ Implicit Object ตามมาตรฐานของ JavaServer Page

 
ตาราง 1-3 Implicit Object
  

Image

 

จากการใช้งาน JSP จะพบว่าโปรแกรมได้ง่ายกว่า Servlet เนื่องจากโปรแกรมเมอร์สามารถนำไฟล์ html ที่ได้จาก Web Designer มาโค้ดโปรแกรม Java ใส่ลงไปได้ทันที และยังสามารถใช้ Implicit Object ที่ Serlvet Container จัดไว้ให้อยู่แล้วได้อีกด้วย อย่างไรก็ตาม การเขียนโปรแกรมใน JSP ยังคงมีข้อเสียหลายอย่างอยู่ เช่น
1.     กระบวนการที่เขียนใส่เข้าไปในไฟล์ jsp จะฝังติดอยู่ในหน้าเว็บนั้น ไม่สามารถ reuse ไปเรียกใช้ได้ในหน้าเว็บอื่น
2.     เนื่องจากโค้ด Java เข้าไปปะปนกับ HTML ดีบักโปรแกรมลำบาก เนื่องจากส่วน Scriptlet และ Expression จะกระจัดกระจายอยู่ในไฟล์ jsp ได้หลายบริเวณ
3.     เมื่อนำไฟล์ jsp กลับไปให้ Web Designer ตกแต่งหน้าเว็บใหม่อีกครั้ง จะพบว่าบางครั้งเครื่องมือที่ใช้ตกแต่งหน้าเว็บจะแสดงผลออกมาไม่ถูกต้องและมีซอร์สโค้ด Java หลุดออกมาเป็นขยะในบางครั้ง(แล้วแต่ยี่ห้อและรุ่นของเครื่องมือที่ใช้)
 

3. แนะนำ Custom Tag
Custom Tag เป็น API ที่ขยายการทำงานต่อจาก Servlet และ JSP โดยอนุญาติให้โปรแกรมเมอร์สามารถสร้างแท็กขึ้นใช้เองได้ในหน้าเว็บ แท็กในที่นี้เขียนยึดตามกฏเกณฑ์เช่นเดียวกับ  xml tag ตัวอย่างของ Tag ที่เราออกแบบมาให้แสดงผลปฏิทินบนหน้าเว็บ อาจจะออกแบบมาให้เรียกใช้ ดังนี้
 
     

 
และเมื่อ Servlet Container คอมไพล์ไฟล์ jsp ตัว Container จะเปลี่ยน Custom Tag ที่พบในหน้าเว็บให้กลายเป็นโค้ด Java ที่ไปเรียกใช้คลาสที่เราจัดเตรียมไว้ให้กับแท็ก เราเรียกคลาสที่จะถูกรันคู่กับแท็กว่า Tag Handler 
 

3.1 ประเภทของ Tag
Custom Tag แบ่งออกเป็น 2 ประเภทคือแท็กแบบที่ไม่มี Body และแท็กแบบที่มี Body ตัวอย่างของแท็กที่ไม่มี Body เช่น

 
 
 
หรือเขียนแบบย่อได้เป็น
 
                       

 
แท็กประเภทที่ 2 คือแบบที่มี Body อยู่ระหว่างแท็กด้วย เช่น
  
                     

          
1929-2939
          
Animal Kingdom
          
50
      


ให้สังเกตว่าเนื้อหาส่วนที่เป็น Body ของแท็ก อาจจะเป็นข้อความอะไรก็ได้ หรืออาจจะเป็นแท็กอีกแท็กหนึ่งก็ได้ เช่นจากตัวอย่าง book ข้างต้น ภายใต้แท็ก book:create จะมีเนื้อหาเป็นแท็ก book:isbn, book:title และ book:price ส่วนในแท็ก book:isbn, book:title และ book:price จะมีเนื้อหาเป็นสตริงข้อความธรรมดา

3.2 คลาสและอินเตอร์เฟสที่ใช้ในการสร้าง Tag Handler
คลาสและอินเตอร์เฟสที่ใช้สำหรับสร้าง Tag Handler จะจัดเตรียมไว้ให้ในแพคเกจ javax.servlet.jsp.tagext ดังปรากฏในรูปภาพ 2-2 โดยประกอบด้วยอินเตอร์เฟสหลักๆ 3 ตัวคือ  Tag,  IterationTag  และ  BodyTag  และประกอบด้วย  Abstract Class ที่ช่วยให้โปรแกรมเมอร์สามารถนำไปสืบทอดต่อได้ทันทีคือคลาส  TagSupport  และ  BodyTagSupport 
 

ตารางที่ 1-4 วัตถุประสงค์ของ interface และ class ที่อยู่ในโครงสร้างพื้นฐานของ Tag Handler

Image
Image

ตารางที่ 1-5
 ค่าคงที่ภายใน Tag Handler

Image 



Image

Thursday, May 10, 2007

Java platform

Java platform includes
++ Development tools
++ Application programming interface (API)
++ Deployment technologies
++ User interface toolkits – AWT, Swing
++ Integration libraries
Several java platforms include
++ Java SE (standard edition)
++ Java EE (enterprise edition)
++ Java ME (Micro edition)
For Java SE, you may download
++ JDK (Java Development Kit) – JRE included
++ JRE (Java Runtime Library)
Both versions include JVM (Java Virtual Machine)
Documentation (Javadoc) is downloaded separately.

Java link

Java
.... http://java.sun.com/
Java Tutorial (e-book) – available on the web
.... http://java.sun.com/docs/books/tutorial/
Java more e-books
.... http://java.sun.com/docs/books/
Java API reference online (javadoc)
.... http://java.sun.com/j2se/1.5.0/docs/api/index.html
Thinking in Java e-book
.... http://www.mindview.net/Books/TIJ/
Others
.... http://www.javaworld.com/
.... http://www.onjava.com/
.... http://www.ibm.com/developerworks/java/
.... http://java.net/
.... http://www.developer.com/java/

Welcome to Program Java

Exsample code java

Study Code Program Java ©Template Blogger Green by Dicas Blogger.

TOPO