Struts 2 Basic in Myanmar


သူငယ္ခ်င္းေရ……..

ဒီေန႔ေတာ့ မင္းအတြက္ အသံုး၀င္မယ္ထင္တဲ့ အေၾကာင္းအရာတစ္ခုကို ေျပာျပခ်င္တယ္ကြာ။ အဲဒါက Apache Struts 2 အေၾကာင္းပါ။ မင္းသိျပီးသားလည္း ျဖစ္ခ်င္ျဖစ္မွာေပါ့။ ငါသိထားတဲ့ အေျခခံ အေၾကာင္းေလးပါ။

Apache Struts 2 ဆိုတာ Enterprise-real Java web applications ေတြလုပ္ဖို႔ အတြက္ အသံုး၀င္တဲ့ Framework တစ္ခုပါ။ သူ႔ရဲ႔ Framework က Extensible ျဖစ္တယ္။  အဲဒီ Framework က Development Cycle ကိုအေကာင္းဆံုးျဖစ္ေအာင္ ေထာက္ပံ့ေပးထားတယ္။ စျပီး တည္ေဆာက္တဲ့ အဆင့္ကေန အသံုးခ်တဲ့ အဆင့္ အဲဒီကေန..ျပင္ဆင္မွဳေတြ လုပ္ရတဲ့ အထိ လြယ္လြယ္ကူကူ လုပ္ႏိုင္ေအာင္ ေထာက္ပံ့ေပးတာေပါ့။

Apache Struts 2 ကို အရင္တုန္းက WebWork 2 လို႔ ေခၚတယ္။ ႏွစ္ေတြၾကာျပီးတဲ့ ေနာက္ WebWork နဲ႔ Struts ေပါင္းစပ္ျပီး Struts 2 ျဖစ္လာတယ္။ Version အသစ္ျဖစ္ေပမယ့္ အရင္တုန္းက Struts လိုပဲ အသံုး၀င္ပါတယ္။ ပိုျပီးေတာ့ ေကာင္းလာတယ္လို႔ ဆိုရမယ္။ www.struts.apache.org ဆိုတဲ့ site မွာ ၀င္ျပီးေလ့လာလို႔လည္းရတယ္။

ငါလည္း အခုမွ စျပီး Struts 2ကို ေလ့လာေနျပီ။ ငါေျပာတာေတြမွာ မွားတာေတြပါရင္ လည္း ျပဳျပင္ေပးပါကြာ။ သူငယ္ခ်င္း MVC Structure ဆိုတာကို ၾကားဖူးမွာ ေပါ့။ Model View Controller ဆိုတာေလ။ အခုခတ္စားေနတဲ့ Design Structure တစ္ခုေပါ့။ Struts 2 က လည္း အဲဒီ Structure ကို အေကာင္အထည္ေဖၚႏိုင္ေအာင္ လုပ္ေပးတဲ့ Framework တစ္ခုေပါ့။ သူ႔ရဲ ႔ အားသာခ်က္ေတြကေတာ့ အမ်ားၾကီးပဲကြ။ မင္းအားတဲ့ အခါထပ္ျပီး ေလ့လာၾကည္႔ေပါ့ကြာ။ ငါတို႔ရဲ ႔ ေဘာ္ဒါၾကီး www.google.com က ငါတို႔သိခ်င္တာ ဘယ္ဟာမဆို သိေအာင္လုပ္ေပးေနတာပဲ မဟုတ္လား။

Apache Struts2 ရဲ ႔ အဓိက စြမ္းေဆာင္မွဳေတြက သူက Pluggable Framework Architecture ကြ။ ဆိုလိုတာက မင္းလိုအပ္သလို Customize လုပ္ျပီးသံုးႏိုင္တယ္။ Flexible Validation Framework ျဖစ္လို႔ Validation Rules ေတြကို Action Code ေတြက ေနခြဲထြက္ျပီး လုပ္ႏိုင္လာတယ္။ Action Code ေတြမွာ ေရးစရာ မလိုေတာ့ဘူးေပါ့။ Hierarchical approach နဲ႔ Localizing applications ေတြကို Internationalization လုပ္လာတယ္။ သူက Integrated dependency injection engine တစ္ခုျဖစ္ျပီး component lifecycle နဲ႔ dependencies ေတြကို အေကာင္းမြန္ဆံုး manage လုပ္ေပးတယ္။ Default အေနနဲ႔ သူက Spring ကို သံုးျပီး dependency injection ေတြကုိ ေျဖရွင္းတယ္။ သူ႔မွာ Modular configuration files ေတြရွိျပီး packages ေတြ namespaces ေတြကို သံုးျပီး ၾကီးမားတဲ့ projects(actions ေပါင္း ၁၀၀ ေလာက္ပါတဲ့) ေတြကို ေကာင္းေကာင္းၾကီးကို manage လုပ္လို႔ ရတယ္။ Java 5 annotations ျဖစ္လို႔ configuration overhead ေတြကို ေလ်ာ့က်ေစတယ္။ *(Java 1.4 က minimum platform)

သူငယ္ခ်င္းေရ… မင္းသိတဲ့ အတိုင္း web ဆိုတာ သံုးတဲ့ သူက ေတာင္းဆိုမွ စျပီး အလုပ္လုပ္တာမဟုတ္လား။ Apache Struts 2 လည္း ဒီလိုပဲ။ သူ႔ ရဲ ႔ Request Processing အေၾကာင္းကို ေျပာရမယ္ဆိုရင္……

၁။ web browser က resource ေတြျဖစ္တဲ့ /mypage.action, /reports/myreport.pdf စတာေတြကို request လုပ္မယ္။

၂။ Filter Dispatcher ဆိုတဲ့အရာက request ေတြကို ၾကည္႔ျပီး သင့္ေတာ္တဲ့ Action ေတြကို ဆံုးျဖတ္ေပးတယ္။

၃။ Interceptors ဆိုတဲ့အရာက အလိုအေလ်ာက္ ေယဘူယ်ျဖစ္တဲ့ လုပ္ေဆာင္ခ်က္ေတြကို apply လုပ္ေပးတယ္။ workflow, validation, file upload handling စတဲ့ အရာေတြကို ေပါ့။

၄။ Action method က လုပ္ေပးတာကေတာ့ မ်ားေသာအားျဖင့္ information ေတြကို Database မွာ သိမ္းတာေတြ၊ ယူတာေတြကို အဓိက လုပ္တယ္။

၅။ Result ဆိုတဲ့အရာကေတာ့ output ေတြကို Browser ကို ျပန္ပို႔ေပးတဲ့ဟာေပါ့။ HTML, images, PDF စတဲ့ အရာေတြ အေနနဲ႔ ပို႔ေပးတယ္။

Struts 2 မွာ လုပ္ထားတဲ့ improvements ေတြက……

Design ပိုင္းကို ႐ိုးရွင္းစြာျပဳလုပ္ထားတယ္။ struts 1 မွာတုန္းကၾကံဳေတြခဲ့ရတဲ့ Design Problem တစ္ခုျဖစ္တဲ့ interfaces အစား abstract classes ေတြကို ေရးခဲ့ရတာေတြကို struts 2 မွာ ေျဖရွင္းထားတယ္။ Struts 2 ရဲ ႔ classes ေတြက မ်ားေသာအားျဖင့္ interfaces အေပၚမွာ အေျခခံထားတယ္။ သူ႔ရဲ ႔ အဓိက interfaces ေတြက HTTP အေပၚမွာလည္း မွီခိုမွဳ ကင္းတယ္။

Intelligent Defaults ျဖစ္တယ္။ configuration elementsေတြက မ်ားေသာအားျဖင့္ default value ေတြပါျပီးေတာ့ လိုအပ္သလို ထားျပီး သံုးႏိုင္တယ္။ xml ကို အေျခခံထားတဲ့ default configuration files ေတြပါျပီးေတာ့ အဲဒါေတြကို လည္း လိုအပ္သလို extended လုပ္ႏိုင္တယ္။

Results ပိုင္းမွာလည္းတိုးတက္လာတယ္။ ActionForwards နဲ႔ မတူေတာ့ပဲ Struts 2ရဲ ႔ Results ေတြက အမ်ိဳးစံုလင္တဲ့ outputs ေတြ ထုတ္ ႏိုင္ေအာင္ flexible ျဖစ္လာတယ္။

POJO (Plain Old Java Object) Action’s အေနနဲ႔ ေျပာရရင္ Struts 1 မွာတုန္းက Actions ေတြက Servlet API ကို မွီခိုထားတယ္။ HttpServletRequest နဲ႔ HttpServletResponse objects ေတြက execute() method ကို pass လုပ္တယ္။ Struts2 မွာၾကေတာ့ ဘယ္ java class မဆို execute() method ပါရင္ Action class အေနနဲ႔ သံုးလို႔ရတယ္။ Actions ေတြက underlying framework မွာ neutral ျဖစ္ရမယ္။

Struts 2 Framework မွာ ActionForm’s ေတြမရွိေတာ့ဘူး။ ႐ိုးရွင္းတဲ့ JavaBean ေတြကိုပဲ propertyies ေတြတိုက္႐ိုက္ပို႔ဖို႔ သံုးေတာ့တယ္။

Testing အတြက္လည္း Enhancement ေတြလုပ္ထားတယ္။ Struts 2 ရဲ ႔ Actions ေတြက HTTP independentျဖစ္ျပီး Framework နဲ႔လည္း neutral ျဖစ္တဲ့ အတြက္ struts applications ေတြကို test လုပ္တဲ့အခါမွာ အလြန္လြယ္ကူျပီး mock objects ေတြကို လည္းျပန္ျပီး စီစဥ္ေနရမွဳေတြ မရွိေတာ့ဘူးေပါ့။ mock objects ဆိုတာက objects ေတြကို unit testလုပ္တဲ့ အခါမွာ ၾကားခံအေနနဲ႔ လုပ္ေဆာင္တဲ့ အရာတစ္ခုပါ။

Tag Features ေတြပိုေကာင္းလာတယ္။ Struts 2 tags ေတြက style sheet-driven markup ေတြကို ထည္႔သံုးႏုိင္တဲ့ စြမ္းရည္ေတြရွိလာတယ္။ consistent ျဖစ္တဲ့ pages ေတြကို code နည္းနည္းနဲ႔ ေရးႏိုင္လာမယ္။ Struts 2 tage markup ေတြကို underlying stylesheet ကေနျပင္ႏုိင္တယ္။ Struts 2 tags ေတြက ပိုျပီးစြမ္းေဆာင္ရည္ ျမင့္လာတယ္။ result oriented ျဖစ္လာတယ္။ JSP ေရာ FreeMaker tags ေတြေရာ ႏွစ္ခုလံုးကို အျပည္႔အ၀ support လုပ္ေပးထားတယ္။

Annotations Support အေနနဲ႔ Java 5 annotations ကို XML နဲ႔ Java properties configurations ရဲ ႔ alternative အေနနဲ႔ သံုးထားတယ္။

(Stateful Checkboxes)Struts 2 ရဲ ႔ checkboxes ေတြက မွားယြင္းတဲ့ values ေတြ အတြက္ special handling ေတြ မလိုအပ္ေတာ့ဘူး။

(Quick Start)ေျပာင္းလဲမွဳေတြကို လွ်င္လွ်င္ျမန္ျမန္ လုပ္ႏိုင္တယ္။ web container ကို ျပန္စစရာမလိုဘူး။

သူငယ္ခ်င္းလိုအပ္ရင္ request handling ေတြကို action အလိုက္ customize လုပ္လုိ႔ရတယ္။ Customizable Controller ေပါ့။

Spring Beans ကို add လိုက္တာနဲ႔ပဲ Strus 2 Actions ေတြက Spring-aware ျဖစ္သြားတယ္။ Easy Spring Integration ေပါ့။

Struts 2 ရဲ ႔ extensions ေတြကို JAR file ကို drop လုပ္လုိက္တာနဲ႔ပဲ add လုပ္ႏိုင္ပါတယ္။ XML တို႔ properties files ေတြကို ထည္႔စရာ မလိုပါဘူး။

Ajax ကိုလည္း Support လုပ္တယ္။ AJAX client side validation ေတြ၊  Remote form submission support(work with the submit tag as well) ေတြ လုပ္ေပးတယ္။ Partial HTML ေတြကို  dynamic reloading လုပ္ေပးတဲ့ advanced div template ေတြ၊ JavaScript ေတြကို remotely load ေတြ evaluate ေတြ လုပ္ႏိုင္တဲ့ စြမ္းရည္ေတြ ေထာက္ပံ့ေပးတဲ့ advanced template ေတြ၊ AJAX -only tabbed Panel implementation ေတြ၊  rich pub-sub event model ေတြ၊ interactive auto complete tag ေတြ ကို support လုပ္ေပးထားတယ္။

ဒါေတြက Apache Struts 2 ရဲ ႔ ပိုမိုေကာင္းမြန္လာတဲ့ အေၾကာင္းေတြပဲ။ သူငယ္ခ်င္းေရ စာေတြ အမ်ားၾကီးဖတ္ခိုင္းလို႔ ပ်င္းေနျပီလား။ OK! ဒီေန႔ေတာ့ ဒီေလာက္ပဲကြာ။ ငါလည္းစာေတြေရးရတာ ပ်င္းလာျပီ။

ေနာက္ေန႔ၾကမွ Apache Struts ရဲ ႔ အလုပ္လုပ္ပံုေတြကို ေျပာ ျပေတာ့မယ္။

မင္းကို ခင္မင္တဲ့….

KG,

သူငယ္ခ်င္းေရ……..

မေန႔က Apache Struts 2 အေၾကာင္း ဖတ္ျပီး ဘယ္လိုလဲ။ ဂြမ္းေနျပီလား။ လန္းေနျပီလား။

ဒီေန႔ေတာ့ Apache Struts 2 ရဲ ႔ လုပ္ေဆာင္ပံုေတြ အေၾကာင္းဖတ္ၾကည္႔ရေအာင္………….

Apache Struts 2 မွာ….

Action

Action or POJO

Result

struts.xml

FilterDispatcher

Interceptors

Action-validation.xml

ဆိုတာေတြရွိတယ္။

ACTION

Action ဆိုတာဘာလဲ။ Action is a basic “unit-of-work” ပဲ။ သူက execute() ဆိုတဲ့ method ပါတဲ့ POJO class တစ္ခုပဲ။ POJO ဆိုတာက Plain Old Java Object။ ပိုသိခ်င္ရင္ ေဘာ္ဒါၾကီးကိုေမး(www.google.com)။ ဆိုေတာ့ Action ဆိုတာ java file ေတြပါပဲကြာ အရွင္းဆံုးေျပာရရင္။

သူမွာ Action Mapping Configuration ေတြလုပ္ရမယ္။ struts.xml မွာေရးရမွာေနာ့္။ Action class ကို identifier တစ္ခုနဲ႔ map လုပ္ရမယ္။ request တစ္ခုက action name တစ္ခုကို matches လုပ္ျပီဆိုရင္၊ Framework က mapping ကို သံုးျပီး request ေတြကို ဘယ္လုိ process လုပ္ရမလဲလို႔ ဆံုးျဖတ္ေပးတယ္။ ျပီးေတာ့ a set of result types, a set of exception handlers, an interceptor stack ေတြကိုလည္း specifies လုပ္ေပးတယ္။

Example; Action Mapping

<action>

<result type=”redirect-action”>Menu</result>

<result name=”input”>/tutorial/Logon.jsp</result>

</action>

Action Names (name attribute)

Attribute အမည္ေတြကို browser request ရဲ ႔ အစိတ္အပိုင္းတစ္ခုအေနနဲ႔ match လုပ္တယ္။ Framework က host, application name, extension ကို drop လုပ္ျပီး အလယ္မွာဘာရွိလဲဆိုတာကို match လုပ္ေပးတယ္။

ဥပမာ။

Http://www.planetstruts.org/struts2-mailreader/Welcome.do အတြက္ request လုပ္ရင္ Welcome action ကို map လုပ္လိမ့္မယ္။

Action Names

Application တစ္ခုထဲမွာ action ကို link လုပ္တဲ့အခါ အမ်ားအားျဖင့္ Struts Tag ကပဲ generate လုပ္ေပးတယ္။ tag က action ေတြကို နာမည္ေပး၊ framework ကတျခားလိုအပ္တာအားလံုးလုပ္ေပးတယ္။

<s:form action=”Hello”>

<s:textfield label=”Please enter your name” name=”name”/>

<s:submit/>

</s:form>

Example: Using Struts Tag

<%@ taglib prefix=”s” uri=”/WEB-INF/struts-tags.tld%>

<html>

<head><title>Add Blog Entry</title></head>

<body>

<s:form action=”save” method=”post”>

<s:textfield label=”Title” name=”title”/>

<s:textarea label=”Entry” name=”entry” rows=”3″ cols=”25″/>

<s:submit value=”Add”/>

</s:form>

</body>

</html>

Action Interface

Handler class ကို entry လုပ္မယ့္ default method ကို Action interface ကdefine လုပ္ေပးတယ္။

Public interface Action{

Public String execute() throws Exception;

}

Action interface ကို က မေရးေပးလည္းရတယ္။ optional ပဲ။

Action Methods

တစ္ခါတစ္ေလ၊ action အတြက္ entry point ေတြ တစ္ခုမကေရးေပးရတတ္တယ္။ ဥပမာ data-access Action မွာဆိုရင္၊ entry points ေတြျဖစ္တဲ့ create, retrieve, update and delete ေတြကို လုပ္ေပးရမယ္။ ကြဲျပားတဲ့ entry points ေတြကို method attribute နဲ႔ specify လုပ္လုိ႔ရတယ္။

<action method=”delete”>

တကယ္လို႔ execute method သာ configuration မွာ မရွိဘူးဆိုရင္ေတာ့ framework က exception throw လုပ္လိမ့္မယ္။

Wildcard Method

A set of action mappings ေတြက common pattern ေတြကိုပဲ share လုပ္သံုးတယ္။ action mapping ေတြကို တစ္ခုစီေရးေနမယ့္အစား wildcard mapping နဲ႔အားလံုးေပါင္းျပီး တစ္ခါတည္းေရးလို႔ရတယ္။

Example: Wildcard Method

Example 1

<action class=”example.Crud” method=”{1}”>

ဒါဆိုရင္ တကယ္လို႔ edit method ကိုေခၚခ်င္ရင္ “editCrude” ကို reference လုပ္တာနဲ႔ပဲရျပီ။တျခား method ေတြလည္း ထိုနည္း၄င္းပဲ။

Example 2

<action class=”example.Crud” method=”{1}”>

Action Default

တကယ္လို႔ မင္းက action handle ကို unmatched requests ေတြ အတြက္လည္း အလုပ္လုပ္ေစခ်င္ရင္ default action တစ္ခု လုပ္ထားလို႔ ရတယ္။

<package extends=”action-default”>

<default-action-ref name=”UnderConstruction”>

<action>

<result>/UnderConstruction.jsp</result>

</action>

Wildcard Default

Wildcards ကိုသံုးတာကလည္း default actions approach အတြက္ နည္းတစ္နည္းပဲ။ configuration အဆံုးက wildcard action မွာ unmatched references ေတြကို catch လုပ္ႏိုင္ေအာင္ သံုးလို႔ရတယ္။

<action>

<result>/{1}.jsp</result>

</action>

RESULT

Action class method လုပ္ေဆာင္တာေတြျပီးသြားရင္ သူက String Return ျပန္တယ္။ အဲဒီ String ရဲ ႔ value ကုိ result element ေတြကို select လုပ္တဲ့ ေနရာမွာ သံုးတယ္။ Action mapping မွာ ကြဲျပားတဲ့ ျဖစ္ႏုိင္ေျခ outcomes ေတြကို ကိုယ္စားျပဳတဲ့ a set of results ေတြရွိတယ္။

Tokens လို႔ေခၚတဲ့ Predefined result names ေတြလည္းရွိတယ္။

String SUCCESS =”success”;

String NONE =”none”;

String ERROR=”error”;

String INPUT=”input”;

String LOGIN=”login”;

Applications ေတြကေန တျခား cases ေတြနဲ႔ သင့္ေတာ္မယ့္ result names ေတြကိုလည္း သက္မွတ္ႏိုင္တယ္။

Result Element

Result element က name attribute ေတြနဲ႔ အတူ logical name ေတြကို provide လုပ္ေပးတယ္။ Action တစ္ခုက implementation details အေၾကာင္းေတြကို သိစရာမလိုပဲ “success” or “error” token ေတြကို pass back လုပ္ႏိုင္တယ္။တကယ္လို႔ name attribute မေပးထားရင္၊ framework က “success” လုိ႔နာမည္ ေပးလိမ့္မယ္။

Result element က Result Type(with type attribute) ကို provide လုပ္ေပးတယ္။ results ေတြက အမ်ားအားျဖင့္ server page or template ကိုပဲ ႐ိုး႐ိုးေလး forward လုပ္ပါတယ္။ဒါေပမယ့္ တစ္ျခား Result Types ေတြကို ပိုျပီးစိတ္၀င္စားစရာေကာင္းတဲ့ေနရာမွာ သံုးလို႔ရတယ္။ တကယ္လို႔ type attribute ကို specify မလုပ္ခဲ့ဘူးဆိုရင္ framework က dispatcher ကိုသံုးပါလိမ့္မယ္။

Result Element without defaults

<result type=”dispatcher”>

<param name=”location”>/ThankYou.jsp</param>

</result>

Result element using some defaults (as as above)

<result>

<param>/ThankYou.jsp</param>

</result>

Result element using default for the <param> as well

<result>/ThankYou.jsp</result>

Example:Multiple Results

<action>

<result>/hello/Result.jsp</result><!–name=”success” –>

<result>/hello/Error.jsp</result>

<result name=”input”>/hello/Input.jsp</result>

</action>

RESULT TYPE

Predefined Result Types

  • Dispatcher Result
  • Redirect Action Result
  • Chain Result
  • Redirect Result
  • FreeMarker Result
  • Velocity Result
  • PlainText Result
  • Tiles Result
  • HttpHeader Result
  • Stream Result

Setting a default Result Type

တကယ္လို႔ type attribute သာ specified လုပ္မထားရင္ framework က dispatcher ကိုသံုးလိမ့္မယ္။ သူက အျခား web resource ကို forward လုပ္ေပးတယ္။ အဲဒါကို package တစ္ခုစီရဲ ႔ configuration မွာ set လုပ္ေပးလို႔လည္းရတယ္။

<result-types>

<result-type class=”org.apache.struts2.dispatcher.ServletDispatcherResult” default=”true”/>

</result-types>

Global Results

မ်ားေသာအားျဖင့္ results ေတြက action element ၾကားမွာ nested အျဖစ္ရွိတယ္။ ဒါေပမယ့္ အခ်ိဳ ႔ၾကေတာ့ multiple actions ကို apply လုပ္တယ္။ ဥပမာအားျဖင့္ လံုျခံဳေရးဦးစားေပး application မွာ client က page တစ္ခုကို authorize မဟုတ္ပဲလဲ access လုပ္ခ်င္မွာပဲ၊ ဒါဆိုရင္ actions ေတြအမ်ားၾကီးက “logon” result ကို access လုပ္ဖို႔ လုိအပ္လာျပီ။

တကယ္လို႔ actions ေတြက results ေတြကို share လုပ္ရမယ္ဆိုရင္၊ package တစ္ခုစီအတြက္ a set of global results ေတြကို defined လုပ္ေပးႏုိင္တယ္။ framework က ပထမဆံုး action ထဲမွာရွိတဲ့ nested ျဖစ္ေနတဲ့ local result ကို အရင္ရွာတယ္။ တကယ္လို႔ match ျဖစ္တာ မေတြ႔မွပဲ global results ကို checked လုပ္ပါတယ္။

Example: Global Results

<global-results>

<result name=”error”>/Error.jsp</result>

<result name=”invalid.token”>/Error.jsp</result>

<result type=”redirect-action”>Logon!input</result>

</global-results>

Dynamic Results

Execution time အထိ result ကို မသိႏိုင္ပါဘူး။ Result values ေတြကို သူရဲ ႔ သက္ဆိုင္ရာ Action implementation ေတြကတဆင့္ EL expressions (Action’s properties ကို access လုပ္တဲ့ဟာပါ) ကိုသံုးျပီး retrieve လုပ္ႏိုင္ပါတယ္။

Example: Dynamic Results

Give the following Action fragment

Private String nextAction;

Public String getNextAction(){

return nextAction;

}

You might define a result like following

<action class=”FragmentAction”>

<result name=”next” type=”redirect-action”>${nextAction}</result>

</action>

Example: Dynamic Results

ေအာက္က code မွာ တကယ္လို႔ success return ျပန္ရင္ browser က forward လုပ္မွာက /<app-prefix>/myNamespace/otherAction.action?id=<value of id> ကိုပါ။

<action class=”com.project.MyAction”>

<result type=”redirect-action”>otherAction?id=${id}</result>

<result type=”redirect”>${redirectURL}</result>

</action>

Action Chaining

Struts Framework က သက္မွတ္ထားတဲ့ အစီအစဥ္ workflow ေတြထဲကို multiple actions ေတြကို chain လုပ္ႏိုင္တဲ့ အစြမ္းရွိပါတယ္။ ဒီစြမ္းရည္က Action ကို Chain Result ေပးျခင္းျဖင့္ အလုပ္လုပ္ပါတယ္။

Chain Result

Chain Result ဆိုတာက result type တစ္မ်ိဳးပါ။ သူက သူ႔ကိုယ္ပုိင္ Interceptor Stack နဲ႔ Result ကို သံုးျပီး Action ကို invoke လုပ္ပါတယ္။အဲဒီ Interceptor က Action တစ္ခုကို target Action တစ္ခုဆီသို႔ request ကုိ forward လုပ္ေစပါတယ္။

<package extends=”struts-default”>

<!– Chain creatAccount to login, using the default parameter –>

<action class=”….”>

<result>login</result>

</action>

<action>

<!– Chain to another namespace –>

<result>

<param name=”actionName”>dashboard</param>

<param name=”namespace”>/secure</param>

</result>

</action>

</package>

<package extends=”struts-default” namespace=”/secure”>

<action class=”…”>

<result>dashboard.jsp</result>

</action>

</package>

Ok! ဒီေန႔ေတာ့ နည္းနည္းမ်ားသြားျပီ၊ က်န္တာေတြေတာ့ ေနာက္ေန႔မွပဲ။

မင္းကိုခင္တဲ့…

KG,

kaunggyi@gmail.com

…………………………….

“အလင္းေစတမန္”<a_lin_say_ta_mum@googlegroups.com>

“အလင္းေစတမန္” www.groups.google.com/group/a_lin_say_ta_mum

သူငယ္ခ်င္းေရ……..

မေန႔က Apache Struts 2 အေၾကာင္း ဖတ္ျပီး ဘယ္လိုလဲ။

ဒီေန႔ေတာ့ Apache Struts 2 ရဲ ႔ လုပ္ေဆာင္ပံုေတြ အေၾကာင္းဆက္ျပီး ဖတ္ၾကည္႔ရေအာင္………….

Interceptor

ဘာလို႔ interceptor လုိတာလဲ? Actions ေတြအမ်ားၾကီးက ဘံုမွ်သံုးတဲ့ concerns ေတြ အမ်ားၾကီးပဲ။ ဥပမာ အေနနဲ႔ ဆိုရရင္ အခ်ိဳ ႔ actions ေတြက input data ေတြကို စစ္ရမယ္။ အျခား actions ေတြက file upload ကို လုပ္ရတာလည္းရွိမယ္။ အခ်ိဳ႔ action ေတြက double submit မျဖစ္ေအာင္လုပ္ရတာလည္းရွိမယ္။ actions အေတာ္မ်ားမ်ားက page display မလုပ္ခင္မွာ drop-down lists တို႔ တျခား controls ေတြကို လိုမယ္။

Framework က ဒီ ျပႆနာေတြကို interceptor strategy ကို သံုးျပီး အလြယ္တကူ ေျဖရွင္းေပးတယ္။

Interceptors ေတြက Action က invoked ျပီးတာနဲ႔ code ေတြကို execute လုပ္ေပးႏုိင္တယ္။ Framework ေတြရဲ ႔ အဓိက functionality ေတြက မ်ားေသာအားျဖင့္ interceptors ကဲ့သို႔ implemented လုပ္ထားတာ။ double-submit guards, type conversion, object population, စတဲ့ Features ေတြက interceptors ရဲ ႔   အကူအညီနဲ႔ပဲ implemented လုပ္ထားတာပါ။ Interceptor အားလံုးဟာ pluggable ျဖစ္တယ္ေလ။

Interceptors နဲ႔ Actions

အခ်ိဳ ႔အေၾကာင္းေၾကာင့္ Interceptor က Action ေတြကို အလုပ္မလုပ္ေစဘူး။ ဘာလို႔လဲဆိုရင္ double-submit or validation fail ျဖစ္လို႔တဲ့။ interceptors ေတြက Action ရဲ ႔ state ကို execute မလုပ္ခင္မွာ ေျပာင္းလိုက္ႏိုင္တယ္။

Configuration of Interceptors

Interceptors ေတြကို Action ေတြအလုိက္ configure လုပ္လို႔ရတယ္။ Custom Interceptors ေတြက framework က Interceptors ေတြနဲ႔ mix, match လုပ္ ျပီးသံုးလို႔ရတယ္။ Interceptors ေတြက stack ထဲမွာ define လုပ္တယ္။ stack ဆိုတာ execution order ေတြကို သက္မွတ္ေပးတဲ့ဟာပါ။ အခ်ိဳ ႔ ကိစၥေတြမွာ stack မွာ interceptors ရဲ ႔ အစီအစဥ္ကလည္း အေရးၾကီးပါတယ္။

Configurating Interceptors

<package extends=”struts-default”>

<interceptors>

<interceptor class=”..”/>

<interceptor class=”..”/>

</interceptors>

<action class=”tutorial.Login”>

<interceptor-ref/>

<interceptor-ref/>

<result name=”input”>login.jsp</result>

<result type=”redirectr-action”>/secure/home</result>

</action>

</package>

Stacking Interceptors

Web application ေတြအတြက္ တူညီတဲ့ Interceptors set ေတြကို ထပ္ခါထပ္ခါ apply လုပ္ခ်င္ၾကမွာပါ။ ထပ္ခါထပ္ခါ တူညီတဲ့ Interceptors ေတြကို လုပ္ေနမယ့္ အစား Interceptor Stack ကို တဲြသံုးျခင္းအားျဖင့္ ေျဖရွင္းႏိုင္တယ္။

<package extends=”struts-default”>

<interceptors>

<interceptor class=”..”/>

<interceptor class=”..”/>

<interceptor-stackfont-size: 10pt; font-family: “Verdana”,”sans-serif”; color: red;” lang=”EN-US”>myStack”>

<interceptor-ref/>

<interceptor-ref/>

</interceptor-stack>

</interceptors>

<action class=”tutorial.Login”>

<interceptor-reffont-size: 10pt; font-family: “Verdana”,”sans-serif”; color: red;” lang=”EN-US”>myStack”/>

<result name=”input”>login.jsp</result>

<result type=”redirect-action”>/secure/home</result>

</action>

</package>

Interceptor Interface

Interceptors must implement the com.opensymphony.xwork2.interceptor.Interceptor interface

AbstractInterceptor class က init နဲ႔ destroy ရဲ ႔ empty implementation ကို provide လုပ္ေပးတယ္။ ျပီးေတာ့ အဲဒီ method ေတြကို မသံုးဘူးဆိုရင္လည္း ဒါကို သံုးႏိုင္တယ္။

Pulbic interface Interceptor extends Serializable{

void destroy();

void init();

String intercept(ActionInvocation invocation)

Throws Exception;

}

Example: Interceptor

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

Public class SimpleInterceptor extends AbstractInterceptor{

Public String intercept(ActionInvocation invocation)throws Exception{

MyAction action=(MyAction)invocation.getAction();

action.setDate(new Date());

Return invocation.invoke();

}

}

Framework Interceptors

Struts 2 framework က ready-to-use interceptors ေတြကို သံုးလို႔ရေအာင္လုပ္ေပးထားတယ္။ သူတို႔က struts-default.xml ထဲမွာ configured လုပ္ထားတယ္။ အဲဒါေတြကေတာ့….

  • Parameter interceptor: Sets the request parameters onto the Action.
  • Scope interceptor: Simple mechanism for storing Action state in the session or application scope.
  • Validation interceptor: Performs validation using the validators defined in action-validation.xml
  • Many more…….

View Support

View

Themes ေတြ templates ေတြကို သံုးျပီး easy component-oriented development ျဖစ္တဲ့Reusable user interface tags ေတြျဖစ္တယ္။ Tags ranges ေတြက ႐ိုး႐ိုး text fields ကေန advanced tags ေတြျဖစ္တဲ့ date pickers ေတြ tree views ေတြအထိ ရတယ္။ single JavaBean ကဲ့သို႔ multiple objects ေတြရဲ ႔ properties ကို exposes လုပ္ႏိုင္တဲ့ JSTL -comatible expression language (OGNL)ေတြ။ Pluggable Result Types ေတြျဖစ္တဲ့ multiple view technologies ကို support လုပ္ေပးတဲ့ JSP, FreeMarker, Velocity, PDF, and JasperReports ေတြပါတယ္။

View

  • Optional AJAX theme that simplifes creating interactive web applications.
  • Optional Interceptor plugins that can execute long-running queries in the background, prevent multiple form submissions, or handle custom security schemes.

View Technologies

  • JSP, Velocity, FreeMaker, PDF, XSLT

Validation

Built-in Validators

<validators>

<validator class=”..”/>

<validator class=”..”/>

<validator/>

<validator class=”..”/>

<validator class=”..”/>

<validator class=”..”/>

<validator class=”..”/>

<validator class=”..”/>

<validator/>

<validator/>

<validator class=”..”/>

<validator class=”..”/>

<validator class=”..”/>

</validators>

Defining Validation Rules

Per Action class:

-in a file named<ActionName>-validation.xml

Per Action alias:

-in a file named<ActionName-alias>-validation.xml

Inheritance hierarchy and interfaces implemented by Action class

-Searches up the inheritance tree of the action to find default validations for parent classes of the Action and interfaces implemented.

Example: SimpleAction-validation.xml

<validators>

<field>

<field-validator>

<message> You must enter a value for bar.</message>

</field-validator>

<field-validator>

<param>6</param>

<param>10</param>

<message>bar must be between ${min} and ${max}, current value is ${bar}.</message>

</field-validator>

</field>

<field>

<field-validator>

<param name=”regex”>[0-9],[0-9]</param>

<message> The value of bar2 must be in the format “x, y”, where x and y are between 0 and 9 </message>

</field-validator>

</field>

<field>

<field-validator>

<param> 12/22/2002</param>

<param> 12/25/2002</param>

<message>The date must be between 12-22-2002 and 12-25-2002. </message>

</field-validator>

</field>

<field>

<field-validator>

<param>0</param>

<param>100</param>

<message key=”foo.range”>Could not find foo.range!</message>

</field-validator>

</field>

<validator>

<param>foo It bar</param>

<message> Foo must be greater than Bar. Foo=${foo}, Bar=${bar}.</message>

</validator>

</validators>

Client Validation

JavaScript client validation code is generated by the framework

Code you write

<s:form action=”Login” validate=”true”>

<s:textfield key=”username”/>

<s:password key=”password”/>

<s:submit/>

</s:form>

Client Validation

JavaScript code that gets generated by framework

<form namespace=”/example” name=”Login” action=”/struts2-login-clientsidevalidation/example/Login.action”

method=”post”><table class=”wwFormTable”>

<script>

function validateForm_Login(){

form = document.getElementById(“Login”);

clearErrorMessages(form);

clearErrorLabels(form);

}

Example:

<field>

<field-validator>

<message key=”error.password.required”/>

</field-validator>

</field>

<field>

<field-validator>

<message key=”error.password2.required”/>

</field-validator>

</field>

<validator>

<param>password eq password2</param>

<message key=”error.password.match”/>

</validator>

Ok! သူငယ္ခ်င္းဒီေန႔ေတာ့ ဒီအထိပဲကြာ။ ဒီေန႔ အရမ္းကုိ ပူတာ ပဲေနာ္ ရာသီဥတုက…..

ေနာက္မွပဲ။

မင္းကို ခင္တဲ့

KG,

www.groups.google.com/group/a_lin_say_ta_mum

သူငယ္ခ်င္းေရ…….

ဒီေန႔ေတာ့ Struts 2 Basic ရဲ ႔ ေနာက္ဆံုး အပိုင္းကို ဖတ္ျပီး မင္းဆီကိုေရးပို႔လုိက္တယ္။

Configuration Files

struts-default.xml

ဒါကေတာ့ default bundled results, interceptors, interceptor stacks ေတြကို define လုပ္တဲ့ fileကြ။အဲဒါကို မင္းရဲ ႔ application-specific interceptor stacks အေနနဲ႔သံုးလို႔ရတယ္။ ဒီဟာက struts.xml file မွာ auto ပါသြားတယ္။ struts2.jar file မွာေရာပဲ။ ကိုယ့္ရဲ ႔own version အေနနဲ႔သံုးခ်င္ရင္ struts.properties file ထဲက struts.configuration.files setting ကို change လုပ္ႏိုင္ပါတယ္။

Struts-default.xml

<package>

<result-types>

<result-type class=”…”/>

<result-type class=”…” default=”true”/>

….

</result-types>

<interceptors>

<interceptor class=”…”/>

<interceptor class=”..r”/>

…….

<!– Basic stack –>

<interceptor-stack>

<interceptor-ref/>

<interceptor-ref/>

<interceptor-ref/>

<interceptor-ref/>

<interceptor-ref/>

<interceptor-ref/>

……

struts.xml

Framework အတြက္ အဓိက configuration file ျဖစ္ပါတယ္။ ဒီfile က webapp ေအာက္က classpath မွာ ရွိရပါမယ္။ ေယဘူယ်အားျဖင့္ /WEB-INF/classes ေအာက္မွာပါ။

Packages

Packages ဆိုတာက actions, results, result types, interceptors, interceptor-stacks ေတြကို group ဖြဲ႔ျပီး logical configuration unit အေန နဲ႔ လုပ္တဲ့အရာျဖစ္ပါတယ္။ packages ေတြဟာ classes ေတြနဲ႔ conceptually တူပါတယ္။ ဘာလို႔လဲဆိုရင္ သူတို႔ကို extend လုပ္ႏိုင္ overriden လုပ္ႏိုင္လို႔ပါ။

Example:<package>

<package extends=”struts-default” namespace=”/employee”>

<default-interceptor-ref/>

<action method=”list” class=”org.apache.struts2.showcase.action.EmployeeAction”>

<result>/empmanager/listEmployees.jsp</result>

<interceptor-ref/>

</action>

Namespace attribute

Namespace attribute က action configurations ကို logical modules အျဖစ္နဲ႔ အသီးအသီးခြဲထုတ္ႏိုင္တယ္။ တစ္ခုစီမွာ သူ႔ကိုယ္ပိုင္ prefix နဲ႔ေပါ့။ namespaces က action names ေတြၾကားမွာ conflicts ျဖစ္တာကို ေရွာင္တယ္။ သူ႔ကိုယ္ပိုင္ menu or help action နဲ႔ ကိုယ္ပိုင္ implementation ေတြပါတယ္။

Example: Namespace attribute

<package>

<action class=”mypackage.simpleAction>

<result type=”dispatcher”>greeting.jsp</result>

</action>

<action>

<result type=”dispatcher”>bar1.jsp</result>

</action>

</package>

<package namespace=”/”>

<action class=”mypackage.simpleAction”>

<result type=”dispatcher”>moo.jsp</result>

</action>

</package>

<package namespace=”/barspace”>

<action class=”mypackage.simpleAction”>

<result type=”dispatcher”>bar2.jsp</result>

</action>

</package>

PLUG IN

Struts 2 Plug-in Architecture

Plug-in ေတြက framework ကို application ရဲ ႔ classpath မွာ JAR ကို add လုိက္တာနဲ႔ပဲ extend လုပ္ႏုိင္တယ္။ plugins ေတြက JAR ထဲမွာ ရွိတာဆိုေတာ့ အျခားသူေတြနဲ႔ အလြယ္တကူ မွ်သံုးႏုိင္တယ္။

Bundled Plug-in’s

  • JSF plug-in
  • REST plug-in
  • Spring plug-in
  • Tiles plug-in
  • SiteGraph plug-in
  • Sitemesh plug-in
  • JasperReports plug-in
  • JFreeChart plug-in
  • Config Browser plug-in
  • Struts 1 plug-in

STRUTS 2 TAGS

Struts 2 Tags

Struts Tags ေတြက code နည္းနည္းနဲ႔ အလြန္ေကာင္းတဲ့ web application ေတြကို ေရးႏုိင္ေအာင္လုပ္ေပးထားတယ္။

Ok!ဒီေလာက္ဆိုရင္ struts 2 ရဲ ႔ basic က ျပီးသြားပါျပီ။

မင္းကိုခင္တဲ့……

KG,

Kaunggyi@gmail.com

www.groups.google.com/group/a_lin_say_ta_mum

Advertisements

About KaungMyatTun(KaungGyi)

ကၽြန္ေတာ့္အေၾကာင္း အမည္ ။ ။ ေကာင္းျမတ္ထြန္း လို႔ေခၚပါတယ္။ သူငယ္ခ်င္းေတြက ေကာင္းၾကီးလို႔ေခၚပါတယ္။ ေဆြမ်ိဳးေတြက သားၾကီးလို႔ေခၚပါတယ္။ ေမြးေန႔ ။ ။ ၁၉၈၂ တတိယလ ၈ရက္ေျမာက္ေန႔ တနလၤာသားပါ။ ေမြးရပ္ ။ ။ မႏၱေလးနန္းေရွ ႔ မွာေမြးပါတယ္။ ေမြးတယ္ဆိုတာေလာက္ပါပဲ။ ေနတာကေတာ့ ရန္ကုန္မွာပါ။ ပညာအရည္အခ်င္း။ ။ ကြန္ျပဴတာဘြဲ ႔ကို KMD ေက်ာင္းကတဆင့္ London Met ကရပါတယ္။ အဂၤလိပ္စာ အေ၀းသင္လဲ ရထားတယ္။ အလုပ္အကိုင္ ။ ။ ျမန္မာဒီစီအာ လို႔ ေခၚတဲ့ ကြန္ျပဴတာစနစ္တည္ေဆာက္ေရးကုမၸဏီမွာလုပ္ပါတယ္။ အလုပ္ေတြကို ေခါင္းခံသူ အျဖစ္နဲ႔ ဆိုပါေတာ့။ တတ္ခဲ့တဲ့Stateေက်ာင္းေတြက ။ ။ မူၾကိဳကိုေတာ့ ရခုိင္ စစ္ေတြက ခရစ္ယာန္ ေက်ာင္းနဲ႔ ရန္ကုန္ေရာက္ေတာ့ ေဒၚေမၾကည္သိန္းစီမွာ တတ္ခဲ့တယ္။ သူငယ္တန္းကေန ၆ တန္းအထိ အလက(၂) ေတာင္ဥကၠလာမွာ တတ္တယ္။ ၇ တန္း ႏွစ္မွာ ေတာင္ၾကီး အထက (၂) ကို သြားတတ္တယ္။ ျပီးေတာ့ ၈ တန္းကေန ၁၀ တန္းအထိ ရန္ကုန္က အထက (၂) ကမာရြတ္မွာ တတ္တယ္။ တပိုင္တႏိုင္သိတာေလးေတြက ။ ။ OpenSource PL ထဲမွာ Java, PHP, JavaScript, Framewrok ထဲမွာ Struts2, Struts1, Peer, Lucence Proprietary PL ထဲမွာ VB.Net, C#.Net, RPG, VBA DB ထဲမွာ MySQL, MSSQL, DB2, Postgre, Server ထဲမွာ AS400, MSS2003 View all posts by KaungMyatTun(KaungGyi)

6 responses to “Struts 2 Basic in Myanmar

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: