သူငယ္ခ်င္းေရ……..
မေန႔က 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 name="Logon" class="tutorial.Logon">
<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 name="delete" class="example.CrudAction" 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 name="*Crud" class="example.Crud" method="{1}">
ဒါဆိုရင္ တကယ္လို႔ edit method ကိုေခၚခ်င္ရင္ "editCrude" ကို reference လုပ္တာနဲ႔ပဲရျပီ။တျခား method ေတြလည္း ထိုနည္း၄င္းပဲ။
Example 2
<action name="Crud_*" class="example.Crud" method="{1}">
Action Default
တကယ္လို႔ မင္းက action handle ကို unmatched requests ေတြ အတြက္လည္း အလုပ္လုပ္ေစခ်င္ရင္ default action တစ္ခု လုပ္ထားလို႔ ရတယ္။
<package name="Hello" extends="action-default">
<default-action-ref name="UnderConstruction">
<action name="UnderConstruction">
<result>/UnderConstruction.jsp</result>
</action>
Wildcard Default
Wildcards ကိုသံုးတာကလည္း default actions approach အတြက္ နည္းတစ္နည္းပဲ။ configuration အဆံုးက wildcard action မွာ unmatched references ေတြကို catch လုပ္ႏိုင္ေအာင္ သံုးလို႔ရတယ္။
<action name="*">
<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 name="success" type="dispatcher">
<param name="location">/ThankYou.jsp</param>
</result>
Result element using some defaults (as as above)
<result>
<param name="location">/ThankYou.jsp</param>
</result>
Result element using default for the <param> as well
<result>/ThankYou.jsp</result>
Example:Multiple Results
<action name="Hello">
<result>/hello/Result.jsp</result><!--name="success" -->
<result name="error">/hello/Error.jsp</result>
<result name="input">/hello/Input.jsp</result>
</action>
RESULT TYPE
Predefined Result Types
Setting a default Result Type
တကယ္လို႔ type attribute သာ specified လုပ္မထားရင္ framework က dispatcher ကိုသံုးလိမ့္မယ္။ သူက အျခား web resource ကို forward လုပ္ေပးတယ္။ အဲဒါကို package တစ္ခုစီရဲ ႔ configuration မွာ set လုပ္ေပးလို႔လည္းရတယ္။
<result-types>
<result-type name="dispatcher" 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 name="login" 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 name="fragment" 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 name="myAction" class="com.project.MyAction">
<result name="success" type="redirect-action">otherAction?id=${id}</result>
<result name="back" 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 name="public" extends="struts-default">
<!-- Chain creatAccount to login, using the default parameter -->
<action name="createAccount" class="….">
<result type="chain">login</result>
</action>
<action name="login" class="…">
<!-- Chain to another namespace -->
<result type="chain">
<param name="actionName">dashboard</param>
<param name="namespace">/secure</param>
</result>
</action>
</package>
<package name="secure" extends="struts-default" namespace="/secure">
<action name="dashboard" class="…">
<result>dashboard.jsp</result>
</action>
</package>
Ok! ဒီေန႔ေတာ့ နည္းနည္းမ်ားသြားျပီ၊ က်န္တာေတြေတာ့ ေနာက္ေန႔မွပဲ။
မင္းကိုခင္တဲ့…
KG,
…………………………….
"အလင္းေစတမန္"<a_lin_sa...@googlegroups.com>
"အလင္းေစတမန္" www.groups.google.com/group/a_lin_say_ta_mum