Thursday, 9 August 2007

ตอนที่​ 2 Struts ​มาลองเล่น​กัน​ดูว่ามันดี​ยัง​ไง


จากตอนที่แล้วบอกคร่าวๆเกี่ยวกับ design patten MVC ว่ามีความหมายอย่างไรในตอนนี้เราจะมาเข้าเรื่องกันครับ เรื่องที่จะอธิบายในตอนนี้คือผมจะเริ่มสร้าง Struts Application อย่างง่ายๆเพื่อให้เข้าใจหลักการทำงานก่อน

ก่อนที่เราจะใช้ Strut Framework นั้นเรามาติดตั้งส่วนต่างๆที่จำเป็นจะต้องใช้ก่อน

1.ติดตั้ง JDK1.4 หรือเวอร์ชั่นสูงกว่า สามารถ download ได้จาก sun

2. ติดตั้ง IDE เพื่อช่วยในการเขียนเช่น Eclipse, Netbeans, JDev หรืออะไรก็แล้วแต่ เพียงแต่ที่ยกตัวอย่างมานั้น Netbean และ JDev นั้น support Struts ด้วยกันทั้งนั้นแต่ Eclipse ไม่ได้ support Struts จึงต้อหา plugin มาช่วยใช้ในการพัฒนา เช่น Exadel หรืออาจจะใช้ Myeclipse ที่รวม plugin สำคัญๆไว้หมดแล้วก็ได้ อันนี้แล้วแต่ครับขึ้นอยุ่กับความถนัดใน IDE ของแต่ละคน ขั้นตอนการใช้งานก้ต่างกันนิดหน่อยครับ แต่ที่ผมใช้คือ Eclipse+Exadel เพราะว่า plugin Exadel ภายในจะประกอบด้วย tomcat, struts framework ซึ่งเราไม่ต้องลง tomcat และ struts เลยมันมีให้เบ็ดเสร็จ เพียงแค่ install plugin Exadel ก็ใช้งานได้เรียบร้อย
ซึ่งถ้าคุณไม่ใช้ plugin Exadel ก็ต้องติดตั้ง Tomcat และ Struts

- ติดตั้ง Tomcat สามารถ download ได้จาก ที่นี่ ซึ่งมีหลาย version ให้ใช้งานและในแต่ละเวอร์ชั่นก็มีหลายแบบให้ download ผมแนะนำให้ download แบบ .zip
เมื่อ download มาแล้วก้ขยาย zip ไว้ก็เรียบร้อย เราใช้ tomcat เพื่อทำหน้าที่เป็น http server และ servlet container
ในส่วนนี้เราสามารถใช้ application server ตัวอื่นๆก็ได้เช่น oc4j, glassfish, jboss, oracle application server ฯลฯ ในตัวอย่างนี้ผมขอใช้ tomcat เพราะไม่กิน resource มากแล้วก็ฟรีครับ ^^

- ติดตั้ง Struts Application download ได้จาก ที่นี่ ในปัจจุบัน Struts ออกเวอร์ชั่น 2 แล้วแต่ที่ผมใช้อยู่เป็น Struts 1.3.8
เมื่อ download มาแล้วให้แตกไฟล์ออกมาจะได้ folder struts-1.3.8 ให้เข้าไป struts-1.3.8\apps จะเห็น war ไฟล์
- struts-black-1.3.8.war เป็น struts application เปล่าๆที่ใช้ในการสร้าง struts application ซึ่งเราจะใช้ไฟล์นี้ในการสร้าง web application ของเรา
- struts-documentation.war จะเป็นที่เก็บ api และ documents สำคัญต่างๆที่เกี่ยวกับการพัฒนา Struts application
- struts-example.war เป็นตัวอย่าง MailReader application เอาไว้ให้เราลองศึกษาดู
จากนั้นให้เรา copy war file พวกนี้ไปที่ \webapps

เมื่อทุกอย่างพร้อมแล้ว มาเริ่มพัฒนา Struts Application กันโดยใน web application ตัวนี้ผมจะสร้าง form ง่ายๆเอาไว้รับข้อมูลที่คุณกรอกแล้วให้แสดงผลในอีก page นึง

1. new project ใหม่ขึ้นมา ถ้าใช้ Eclipse ก็เลือก File > New > Project > Exadel Studio > Struts > Struts Project และทำการตั้งชื่อ Project กับ Struts ที่ใช้ จากนั้น Eclipse จะสร้าง project ที่พร้อมกับการใช้าน Struts ให้เราทันที

2. จากนั้นลองมาดูจุดสำคัญที่สุดของ Struts คือส่วนของ Controller คือไฟล์ web.xml จะเห็นว่า Plugin Exadel Studio ได้เพิ่ม tag ที่จำเป็นต่อการใช้งาน Strtus ไว้แล้วได้แก่
- tag servlet-name action ให้ mapping กับ class ActionServlet
- tag init-param config ให้ mapping กับ struts-config.xml ซึ่งเป็นไฟล์ที่ใช้ในการรับ/ส่ง request/response
- tag servlet-name action ให้ mapping กับ url-pattern ที่มีนามสกุล .do ผลลัพธ์ที่ได้คือเมื่อมี request สำหรับ Struts พวกนามสกุล .do ทั้งหลาย จะถูกส่งมาที่ struts-config.xml ซึ่งตรงนามสกุล .do เราสามารถเปลี่ยนเป็นนามสกุลอื่นก็ได้
- tag taglib เพื่อให้ application เราสามารถอ้างถึง taglib ที่ Struts เตรียมไว้ให้ได้


<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
....
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<taglib>
<taglib-uri>/WEB-INF/struts-bean</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-html</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
....
<web-app>


3. จากนั้นคลิกขวาที่ WebContent สร้างไฟล์ welcome.jsp แล้วใส่ code ตามนี้เลยครับ


<html>
<head>
<title>First Struts Application</title>
</head>
<body>
<form name="form1" method="post" action="WebTypeAction.do?" >
Firstname: <input type="text" name="firstName" /> <br/>
Lastname: <input type="text" name="lastName" /> <br/>
<input type="submit" value="submit" />
</form>
</body>
</html>

เป็นแค่ช่องกรอก inputfield 2 ช่องเท่านั้นเอาไว้กรอกชื่อและนามสกุล

4. จากนั้นไปที่ struts-config.xml ใส่ code ตามนี้


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="UserForm" type="org.apache.struts.action.DynaActionForm">
<form-property name="firstName" type="java.lang.String"/>
<form-property name="lastName" type="java.lang.String"/>
</form-bean>
</struts-config>
<action-mappings>
<action name="UserForm" path="/UserAction" type="action.UserAction">
<forward name="users" path="users.jsp"/>
</action>
</action-mappings>
</struts-config>

อธิบาย:
<form-bean>
- name ใช้กำหนดชื่อที่เราจะใช้ในการอ้างถึง formbean ตัวนี้โดยที่ตรงชื่อนี้ต้องชื่อเดียวกับ form ที่อยู่ในหน้า welcome
- type ใช้กำหนดที่อยู่ของ class ActionForm ซึ่งถ้าใช้ class DynaActionForm เราไม่ต้องสร้าง class ActionForm ของเราเอง ActionForm ใช้ในเรื่องของการเก็บข้อมูลออกมาจาก Form บนหน้าเว็บ
<form-property>
- name ใช้กำหนดชื่อให้กับ UserForm ของเราเพื่อใช้ในการอ้างถึงภายหลังใน class Action
- type ใช้กำหนด datatype
<action>
- name ใช้กำหนดชื่อของ formbean ที่จะใช้กับ action นี้
- path ใช้กำหนด path ที่เราสามารถอ้างถึง action นี้ได้
- type ใช้กำหนดที่อยู่ของ class Action
<forward>
- name ใช้กำหนดชื่อ forward
- path ใช้กำหนดไฟล์ที่จะ forward ไปหา

5. ต่อไปจะเป็นการเขียน class Action ที่เอาไว้ควบคุมการรับ request จาก welcome.jsp(view) และจะส่ง request ไปที่ไหนต่อคือเราอาจส่งไปให้ model ที่เขียน class ที่ติดต่อกับ database หรือจะ
ส่งไปให้ class Action หรืออาจจะส่งไปให้ view ก็ได้ แต่ในตัวอย่างนี้เมื่อเข้ามาที่ class Action และทำงานจนเสร็จผมจะส่งต่อไปให้ users.jsp(view)
เริ่มโดยการ new class ขึ้นมาชื่อ UserAction โดยให้อยู่ใน package action จากนั้นนำ code นี้ไปวาง


package action;

public class UserAction extends org.apache.struts.action.Action {

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
String firstName = (String)request.getAttribute("firstName");
String lastName = (Stirng)request.getAttribute("lastName");
request.setAttribute("name", firstName + " " + lastName);
return mapping.findForward(users);
}
}

อธิบาย: class ที่จะเรียกว่าทำหน้าที่ action ได้ต้อง extends มาจาก class org.apache.struts.action.Action และทำการ overrides method execute ซึ่งรับ parameter ที่สำคัญๆของ Struts 2 ตัวคือ
- mapping ใช้ในการเลือก instance
- form นี้จะใส่หรือไม่ใส่ก็ได้แต่ถ้าเราใช้ formbean ก็ต้องใส่ด้วยเพื่อที่จะเอาค่าออกมาจาก formbean
ใน method นี้จะทำการรวมคำระหว่างชื่อกับนามสกุล แล้วส่งออกไปยังอีกหน้านึงผ่านทาง request scope ในตอนสุดท้ายของ method นี้เราสั่ง return ให้ไปหน้า users โดยเดี๋ยว Struts จะไปหาเองว่า object ActionForward มัน mapping กับ forwardname ตัวใดซึ่งตรงนี้ก็ที่เรากำหนดไว้ใน struts-config.xml

6. สร้าง user.jsp ขึ้นมาแล้วใส่ code ตามนี้


<html>
<head>
<title>First Struts Application</title>
</head>
<body>
<% out.println("welcome " + request.getAttribute("name")); %>
</body>
</html>


เมื่อทำงานในส่วน Action เสร็จ มันจะมาที่หน้า users.jsp แล้วแสดง ชื่อและนามสกุลออกมาโดยเอาตัวแปรที่ชื่อ name ออกมาจาก request scope

7. จากนั้นทดสอบ run ดูเลยครับโดยการ start tomcat ขึ้นมาก่อนจากนั้นค่อย run on server ที่หน้า welcome.jsp ทดสอบกรอกชื่อและนามสกุลลงไปกด submit จะเห็นว่าจะไปเปิดอีกหน้า users.jsp แล้วแสดงชื่อนามสกุลออกมา

นี้เป็นการสร้าง web application ง่ายๆโดยใช้ Struts Framework ซึ่งหัวใจของมันจะอยู่ที่ controller สังเกตุดีๆเวลาเขียน class UserAction มันจะคล้ายๆ เวลาเราเขียน Servlet แต่ถ้าใช้ Servlet เราต้องมา getRequest แต่ละตัวเอาเองหรือบางทีเราก้ต้องมา validate เอาเองด้วย ซึ่งตรงนี้ใน Struts มี Struts-Validate เอาไว้ให้เรานำไปใช้ด้วยต้องลองเล่นกันดูครับ ^^

เริ่มเห็นประโยชน์ของการออกแบบตาม MVC รึยังครับ เพราะเราสามารถเขียนขึ้นมาอีก class นึงเพื่อติดต่อกับ database แล้วให้ class Action เป็นตัวจัดการว่า request นี้จะไปติดต่อกับ class ที่ติดต่อกับ database ตัวใด การออกแบบอย่างนี้ทำให้เราสามารถ reuse class ที่เราเขียนไปได้ครับเช่น ถ้าเรามี view 2 ตัวแต่ใช้ database ตัวเดียวกัน เราก็เขียน class ที่ติดต่อกับ database เพียงแค่ class เดียวแล้วให้ class Action เป็นตัวจัดการ ผิดกับแบบที่ถ้าเราเขียน ตัวติดต่อ database ไว้ใน view

ผมหวังว่าบทความนี้คงมีประโยชน์ต่อผู้ที่ต้องการลองเล่น Struts Framework ไม่มากก็น้อย ถ้าผิดพลาดประการใดติชมได้นะครับทุกความคิดเห็นผมจะ นำไปปรับปรุงแก้ไขต่อไปขอบคุณครับที่อ่านจนจบ :>

5 comments:

blogger said...

เนื้อ ๆ เลยครับ ตอนนี้

~inSiderboy said...

น่าลองจัง..ครับ..

llun said...

นี่มัน ... Spring MVC
ดูแล้วมันคล้ายกันจริงๆแฮะ ต้องกลับมาลองหน่อยแล้ว

Samart Jarates said...

สุดยอด

นันทพงศ์ สร้อยกวี said...

สุดยอดมากครับอธิบายง่ายดีจังเลยครับ