http://blog.csdn.net/randomnet/article/details/8656759
Some time ago, the mechanism of the chain is really a long way to go around. Although there are many explanations on chain on the internet, it is not about the big theory, not the example, or just the example, not the meaning behind the digging of examples.
Let's explain the chain:
Chain: The basic use is to create an action chain. The previous action transfers control to the latter action, and the State of the previous action remains in the latter action. The action chain is handled by the chaining interceptor because the interceptor is part of the Defaultstack interceptor stack, and you can use the action chain at any time.
Some people say: Chain is a shared valuestack, others say chain is a shared form parameter. As far as I am concerned, neither of these statements is entirely correct.
Let's look at a chain example:
Struts.xml:
Action1.java[Java] View Plain copy print? <package name= "Default" extends= "Struts-default" > <action name= "Action1" class= "Web.action.Action1" > <result type= "Chain" > action2</result> </action> <action name= "Action2" class= "Web.action.Action2" > <interceptor-ref name= "DefaultStack" ></interceptor-ref> <result>/result2.jsp</result> </action> </package>
[Java] View Plain copy print? public class action1 extends actionsupport { private String str1; private string str2; public string execute () throws Exception { return success; } public string getstr1 () { return str1; } public void setstr1 (StrING&NBSP;STR1) { this.str1 = str1; } PUBLIC&NBSP;STRING&NBSP;GETSTR2 () { return str2; } &NBSP;&NBSP;PUBLIC&NBSP;VOID&NBSP;SETSTR2 (STRING&NBSP;STR2) { this.str2 = str2; } }
Action2.java[Java] View Plain copy print? public class action2 extends actionsupport { private String str1; private string str2; public string execute () throws Exception { return SUCCESS; } public string getstr1 () { return str1; } public voiD&NBSP;SETSTR1 (STRING&NBSP;STR1) { this.str1 = str1; } &NBSP;&NBSP;&NBSP;&NBSP;PUBLIC&NBSP;STRING&NBSP;GETSTR2 () { return str2; } public void setstr2 (STRING&NBSP;STR2) { this.str2 = str2; } }
And then on the JSP file:
result1.jsp [Java] view plain copy print? <form action= "Action1.action" method= "POST" > Str1:<input type= "text" name= "str1" ><br/> Str2:<input type= "text" name= "str2" ><br/> <input type= "Submit" > </form> res ult2.jsp [Java] view plain copy print? <s:debug/> str1:${str1} <br/> str2:${str2} In fact, the entire process is shown in the following illustration:
The results of the operation are also very simple, there is no suspense:
In result1.jsp input: str1=111,str2=222
Display in result2.jsp: str1=111,str2=222
The following goes into the discussion phase:
First modify the next Action1.java, in Action1, modify the str1 in Valuestack as follows: [Java] view plain copy print? public class action1 extends actionsupport { private string str1; private String str2; public string execute () throws Exception { str1= "Set in action1"; return SUCCESS; } //Omit get,set }
to run again.
Enter in result1.jsp: str1=111,str2=222
Display in result2.jsp: str1=111,str2=222
The result is very strange. Why is the result2.jsp not shown str1=set in Action1? Is the value of the modified str1 in Action1.java not written to Valuestack
Let's look at the information printed in the result2.jsp through <s:debug/>.
As you can see from the Debug information:
1 in Action1 's Valuestack, STR1 was indeed successfully modified.
2) But in the valuestack of Action2, STR1 is still the value of the STR1 entered on the page
Is the valuestack in Action1 not shared into the valuestack in Action2?
To learn more about the truth, we continue to do experiments:
Next, I set breakpoints in SetStr1 (String str) in Action2.java to track the assignment of str1 in Action2
Discovery: STR1 was actually assigned a value of two times: the first time is "set in Action1", and the second time is "111"
So you get the results of the run as shown above.
It's weird, isn't it?
I guess the second assignment "111" comes from the form parameter object that was generated after the JSP was submitted, that is, parameters.
To verify the guesswork, we remove the input from the str1 in result1.jsp, as shown in the following code: [HTML] view plain copy print? [Java] view plain copy print? <form action= "Action1.action" method= "POST" > Str2:<input type= "text" name= "str2" ><br/> <input type= "Submit" > </form>
Then rerun result1.jsp
Run the process under:
Enter str2=222 in result1.jsp
Display in result2.jsp: Str1=set in action1,str2=222
OK, so, the changes we made to STR1 in Action1 were successfully passed to Action2, and SETSTR1 () in Action2 was executed only once.
The truth is ready, we still use a picture to show the whole process
So, when you perform step fourth, if you have str1 in the form parameter and in the Action1 Valuestack,
Then the str1 in the form parameter overwrites the str1 in the Action1 valuestack, and the Action2 in the final str1 is based on the str1 in the form parameter
Well, the above is only based on the results of the operation of the speculation and interpretation.
Now go on to write the next half: The mechanism of chain from the point of view of source
Because my source code is all through the reverse compiler jar package, can not guarantee the correctness of 100%, if encountered the wrong place, please point out. And please forgive us first.
On the chain[1]>> of the struts2 in << Finally, a brief diagram is used to represent the chain mechanism:
But in fact, if you consider valuestack, this picture should be drawn like this:
For this figure, the key two steps: 5 and 6, actually involves two interceptors:
1) Chain
2) params
Also say, say chain way of action sharing between valuestack is not wrong, said they share parameters also not wrong
The key is their sequencing and interaction. Let's take a look at the use of these two interceptors in the Struts-default.xml in Struts-core-2.0.11.jar:[Java] View Plain copy print? <pre class= "html" name= "code" ><interceptor-stack name= "DefaultStack" > ... Omit ..... < Interceptor-ref name= "Chain"/> ........ ..... Omitted ........................... <interceptor-ref name= "params" > </ interceptor-stack> </pre><br> <pre></pre > ≪p> note the sequence of the two interceptors: first chain, then params</p> <p> This also determines the order of execution in the above illustration: Perform the action of 6 after performing the 5 action first. </p> <p> strictly speaking, the action sequence description of 5,6,7,8 in the above picture is not very rigorous,</p> <p> really want to say exactly the exact order of execution, is actually first 5,7 then executes 6,7,8.</p> <p> about this, It is understandable that only the call stack of the Set method in the Action2 must be tracked in the debug state. </p> <p> </p> <p> Okay, Next we'll talk about the definition of chain and params. or in Struts-default.xml </p> <pre class= "html" name= "code" > <interceptor name= "Chain" class= " Com.opensymphony.xwork2.interceptor.ChainingInterceptor "/> <interceptor name= "params" class= " Com.opensymphony.xwork2.interceptor.ParametersInterceptor "/> </pre> <p><br> &nbsP To say chain type of result is actually to build a link that places the action object on the access path on the chain,</p> <p> First look at the com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept (actioninvocation invocation) </p > <p> Find key code: ognlutil.copy (O, invocation.getaction (), ctxmap, excludes, includes);</p> <p> This is the action chain, the last action and the last action .... In short, all the action objects </p> <p> that are accessed before the action chain perform ognlutil.copy (...). Which is to assign the values in their valuestack to the valuestack</p> <p><span style= of the current action. Color: #ff6666 "> For a simple example, there are three action</span></p> <p><span style= "Color: #ff6666" >action1,action2,action3</span></p> <p><span style= "COLOR: #ff6666" > When executing Action2, the value of Valuestack in Action1 is assigned to Action2 valuestack</span></p> <p><span style= "COLOR: #ff6666" > When executing Action3, the valuestack of Action1 and Action2 are assigned to Action3 ></p> <p><span style= "color: #ff6666" > by analogy .... </span></p> <p> </p> <p> Look again: com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept (actioninvocation invocation) </p> <p> One of the key method calls: setparameters (action, stack, parameters); </p> <p> Assign the contents of parameters to valuestack</p> <p > </p> <p> However, in the actual use of the process, does not recommend the misuse of chain</p> <p> because, as in the previous example, when there are two action on chain, the,</p> <p> assignment process actually executes 3 times =1+2: Parameters to Action1,action1 to Action2,parameters to action2</p> <p> And so on: when there are 3 action, the assignment process = 6 times =1+2+3</P>&NBSP;&NBsp; <p>........</p> <p> So when the action on the chain too much, actually very oily ... </p> <p> specific process, empty draw a picture to express the next, people will be easier to understand the </p> <p> </p> <p><br> </p> <p> </p>