<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Sung in Blog

               一些技術(shù)文章 & 一些生活雜碎

    This article discusses different combinations of a Struts action class and a form bean and how these combinations can be used.

    本文討論了Struts框架中Action以及Form Bean之間的不同組合方式以及這些組合的使用。



    Full action(
    一個完整的Action)

    This is arguably the most popular form of Struts action. It contains an action class and a form bean. The action mapping for this operation looks like this:

    首先這里要討論的是Struts框架中最常用的組合,即一個Action對應(yīng)一個Form Bean。這樣的對應(yīng)關(guān)系可以用下圖來解釋:                        

    Full action call sequence

    • Struts controller component receives a request.
    • Struts identifies the action mapping which is responsible for request processing.
    • Struts creates a new instance of the form bean, if it was not found in the scope or if the scope has "request" type. If the bean exists in the scope, it is reused.
    • If form bean defines reset() method, it is called (1)
    • Struts populates the fields with request arguments, using mutators (2)
    • Struts calls validate() method if "validate" attribute of action mapping is not set to "false" (3)
    • If validate() returns non-empty ActionErrors object, control is forwarded to an URI identified by "input" attribute of the action mapping (4a)
    • if validate() returns empty ActionErrors object or null, Struts calls execute() method of the action class (4b)
    • execute() method returns an ActionForward object, which is used by Struts to select the destination URI (5)
    • Struts框架的控制器組件接收到一個Request請求;
    • Struts框架通過Action Mapping配置來確定處理這個請求的Action
    • 如果在可見域(scope)內(nèi)不存在該Action對應(yīng)的Form Bean或者可見域?yàn)?/SPAN>Request時,Struts框架創(chuàng)建一個新的(該Action對應(yīng)的)Form Bean的實(shí)例。如果在可見域內(nèi)存在此Form Bean,則可以重用;
    • 如果在Form Bean中定義了reset()方法,則調(diào)用該方法;(1)
    • Struts框架以Request域中的變量自動填充Form Bean中的變量,使用mutators;(2)
    • 如果配置文件(struts-config.xmlAction-Mapping對應(yīng)的validate屬性被設(shè)置為True,那么Struts框架將自動調(diào)用validate()方法;(3)
    • 如果Validate()方法返回一個非空的ActionErrors對象,Struts控制器會將頁面導(dǎo)向至配置文件中定義個某個處理錯誤的頁面;
    • 如果Validate()方法返回的ActionErrors對象為空,Struts框架將會自動調(diào)用ActionExecute()方法;(4b
    • Execute()方法將會返回一個ActionForward的對象,Struts框架會通過這個對象決定頁面的轉(zhuǎn)向地址。(5)

    Consequences and usage tips

    • execute() method of an action class is not called if ActionForm.validate() returns non-empty ActionErrors object. Instead, control is directly routed to the URI defined in "input" attribute of action mapping.
    • "input" attribute of action mapping allows forwarding to an URI only. If you need to redirect, use Controller.inputForward property. This property was introduced in Struts 1.1. When it set to "true" it indicates that Action.input is not a URI, but a name of an Action.forward element.
    • 如果Action對應(yīng)Form Beanvalidate()方法返回的是一個非空的ActionErrors對象,那么ActionExecute()方法將不會被調(diào)用。此時,Struts框架將直接把頁面導(dǎo)向Action Mappinginput屬性定義的錯誤處理頁面;
    • Action Mapping中“Input”屬性指定的僅為一個Form BeanURL路徑。如果需要重定向頁面,應(yīng)當(dāng)使用Controller.inputForward屬性(該屬性在Struts1.1版本中引入)。當(dāng)該屬性被設(shè)為“True”時,表明Input屬性設(shè)置的不是URL而是一個Action.forward元素名。

    Form-only action

    This action combines a custom form bean and the standard ForwardAction class. This type of action can be used when an action has only two outcomes, one of which is an error.

        
    

    Form-only call sequence

    • Struts creates a new instance of the form bean, if it was not found in the scope or if the scope has "request" type. If the bean exists in the scope, it is reused.
    • If the form bean defines reset() method, it is called (1)
    • Struts populates the fields with request arguments, using mutators (2)
    • Struts calls validate() method if "validate" attribute of action mapping is not set to "false" (3)
    • If validate() returns non-empty ActionErrors object, control is forwarded to an URI identified by "input" attribute of the action mapping (4a)
    • if validate() returns empty ActionErrors object or null, control is forwarded to an URI identified by "parameter" attribute of the action mapping (4b)

    Consequences and usage tips

    • There is no action class to put business code in, so all custom code must be called from either reset() or validate() methods of the form bean.
    • validate() performs two functions: validating request arguments, and accessing the business layer.
    • Because action mapping does not contain "forward" elements, control can be only forwarded, but cannot be redirected.
    • One of the possible usages of a form-only action is response rendering. A form bean can receive a business object id with a request, then look up the business object in the business/persistence layer, fill in the form fields and forward to a JSP which would display the result.
    • It may be convenient to use "session" scope for form-only actions, thus implementing caching of output data.

    Action class-only action

    Struts does not require to declare a form bean for an action mapping. Hence the seemingly tautological action-only action.

        
                
                
        
    

    Action-class only call sequence

    • execute() is called on the action class (1)
    • execute() returns ActionForward object; target URI must be defined in a "forward" element of action mapping (2)

    Consequences and usage tips

    • This action does not declare a form bean, thus Struts passes null to execute() method instead of a form bean.
    • If the action receives request parameters, they must be retrieved from the request object manually. Action class-only action may be used if just a few or no parameters are passed with request, otherwise it is easier to use a form bean.
    • Control may be either forwarded or redirected to another action or JSP page. If you are forwarding control to a JSP, make sure that necessary form beans with output data exist in the scope.
    • Action-class only action cannot be called from HTML FORM, because Struts expects to find the form bean definition in an action mapping which serves the FORM. As a workaround, you can call an action-class only action from a link.

    JSP-only action

    This is the most compact, most error-prone and the least useful type of action. It can be used if it is forwarded to from another action, or if there are other means to obtain needed data.

        

    o_IMG04.gif

    The call chain

    • request is received by Struts controller component
    • Struts calls ForwardAction.execute()
    • ForwardAction.execute() forwards control to an action defined in "parameter" attribute of the action mapping.

    Consequences and usage tips

    • This action does not use a form bean, thus it is not created, not initialized, not populated and not passed to an action class.
    • Though I called it JSP-only operation, it can forward to any URI including other action if needed.
    • Because a form bean is not instantiated during the course of this operation, JSP relies on a form bean which was created earlier and is in the scope of the action. Form bean could be created in another action which forwards control to this action, or it could be created with "session" or higher scope during processing of another request.
    • Usage of this action is very limited. For example, it can be used as a switching yard to forward to another action. After application is compiled and deployed, the course of operation can be switched in the config file using this action.

    Two actions, one form

    Struts allows to call one action from another, thus it is possible to implement a simple Chain of Responsibility.

      o_IMG05.gif

    Two-action call sequence and usage tips

    The call sequence does not differ from the full-action case. The problem is, that Struts calls reset() and validate() methods again for the target action, and it populates form bean fields as well. To use form bean as a transport/command object we must prevent overwriting of form bean fields.

    The solution depends on how the target action is called. If the target action is forwarded to, we can use a token in the HttpRequest object to distinguish if an action is the first action in the chain.

    • Check for the token in the reset() method of the form. If token not found, then this action is the first in the chain. If token is found, do not reset form fields, because this is a chained action.
    • Plant a token into the request object. This must be done in reset() method, because it is always called unlike validate(). validate() may be not called if "validate" property is set to "false" in struts-config.xml file.
    • Verify in each mutator, that the action is first in chain. If not, do not allow changing the field value. This prevents Struts from modifying the form fields. ?
    • check for token in validate() method. If not present, validate form fields, because this is the first action in chain.

    You do not need to remove the token from the request object, the request will be disposed automatically.

    If you use redirection to call the target action, you cannot use request token, because request object is recreated after redirection. The following solutions are possible:

    • Read action mapping name. This works only if you have strict rules defining when each action is called. If struts-config.xml is changed, the code would have to be updated.
    • Store a token on the server in the object with session or higher scope. The token should be promptly removed when the last action in chain finishes.
    • Stick a token into the target URI of the response object, it would be passed to a target action as an HTTP request parameter after redirect completes. This solution takes some additional effort, but the result worth it.

    Important: use the same form scope in both actions for predictable behavior.

    Two actions, two forms

    As long as we already have two actions, why not to have two different forms.

        
     o_IMG06.gif      
      

    Two-action, two form usage tips

    The call sequence does not differ from the previous case. But because now we have two different form types and different instances, we can make the code much cleaner.

    This design can be used to handle input and output of web applications. The source action receives the request, the source form validates the input data. If input is valid, the control is redirected to output action. Struts would want to populate form bean fields again, but here is the trick: you can either define fields with different names, or even better, you can define only accessors for the output form bean. Struts uses accessors and mutators to operate on form bean fields, so without mutators it would not be able to modify the fields of the output form.

    The control flow looks like this:

    • Struts calls reset() on the input form bean (1)
    • Struts populates the fields of input form bean using mutators (2). Input form bean does not even have to define the accessors.
    • truts calls validate() on input form bean, which validates request data (3)
    • If validate() returns non-empty ActionErrors object, control is forwarded to an error page identified by "input" attribute of the action mapping (4a)
    • if validate() returns empty ActionErrors object or null, Struts calls execute() method of the input action class (4b)
    • execute() updates business and persistent objects.
    • execute() creates new ActionForward instance with modified URI of the target action, adding to it the ID of an object which must be displayed.
    • if execute() returns "OK", Struts redirects to the output action (5)
    • Struts calls reset() on the output form bean (6)
    • Struts tries to populate the fields of the output form bean, but because there are no mutators defined, they are not changed (7)
    • validate() has nothing to validate in the output form, so it returns null (8)
    • execute() method of the action class locates business object using ID passed with the request, fills out the fields of the output form with business data and returns "OK" (9b)
    • Struts displays the result page (10)

    Because I fill out the output form manually with the persistent data, I do not need to preserve values of the input form bean. Thus, I do not need to use forwarding, and I can employ redirection instead. This way, input action and output action become less tied to each other.

    A very nice side effect of this solution is that output page can be easily reloaded without processing the request in input action again. This helps to prevent double submission of input data.

    More on double submit problem and how it can be defeated see in my other article: Redirect After Post

    About the Author

    Michael holds an MS in Computer Science from Moscow Aviation Institute (technical university), Moscow, Russia. He has more than 10 years of experience developing applications for MS-DOS, Windows and Java platform. he has devoted the last 5 years to server-side Java applications. Curently he is employed as a software engineer at International Lottery and Totalizator, Inc.

    posted on 2005-10-24 22:17 Sung 閱讀(1422) 評論(0)  編輯  收藏 所屬分類: Struts
    主站蜘蛛池模板: 亚洲中文无码亚洲人成影院| 国内精自视频品线六区免费| 亚洲高清有码中文字| 亚洲精品无码MV在线观看| 免费精品人在线二线三线区别| 三年片在线观看免费观看大全动漫| 美女被免费视频网站| 中文字幕亚洲男人的天堂网络| 亚洲国产高清在线| 国产精品亚洲mnbav网站 | 亚洲AV综合色一区二区三区| 成人国产mv免费视频| 91情侣在线精品国产免费| 亚洲精品免费视频| a在线观看免费网址大全| 特级做a爰片毛片免费看| 亚洲av无码一区二区三区人妖| 亚洲另类视频在线观看| 亚洲v高清理论电影| 久久久久无码专区亚洲av| 免费日本黄色网址| 国产精品无码素人福利免费| 嫩草视频在线免费观看| 午夜性色一区二区三区免费不卡视频| 无码精品国产一区二区三区免费 | 久久精品国产免费| WWW国产成人免费观看视频| mm1313亚洲国产精品无码试看| 亚洲 日韩 色 图网站| 亚洲天堂福利视频| 亚洲欧洲日产国产最新| 亚洲日产2021三区| 亚洲国产成人久久99精品| 亚洲第一页在线视频| 亚洲国产精品xo在线观看| 亚洲不卡视频在线观看| 亚洲日本久久一区二区va| 亚洲欧美自偷自拍另类视| 亚洲精品宾馆在线精品酒店| 亚洲AV日韩AV永久无码色欲 | 国产精品视_精品国产免费 |