Dear Wiki user, You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification.
The following page has been changed by MichaelJouravlev: http://wiki.apache.org/struts/StrutsManualActionWebComponentSync ------------------------------------------------------------------------------ 1. The cycle begins with the initial load of a composite page, starting the render phase. 2. When the JSP processor encounters a <c:import> action in a composite page, it generates an HTTP request to obtain the content of the included component. - 3. The Action class forwards to a view relevant to component state. After all components on the composite page have rendered themselves, the render phase finishes and a composite page is presented to a user. + 3. The Action class that manages the component receives an "empty" GET request. The Action class forwards to a view relevant to component state. After all components on the composite page have rendered themselves, the render phase finishes and the composite page is presented to a user. - 4. The user initiates the input phase by submitting an HTML form or by activating a command link. The browser sends input data to an Action that manages component events and state. The Action processes data and updates component state if needed. Component state can be stored in a session-scoped form bean, in a database or in other location. + 4. The user initiates the input phase by submitting an HTML form or by activating a command link. The browser sends input data to an Action that manages the component. The Action processes data and updates component state if needed. Component state can be stored in a session-scoped form bean, in a database or in other location. 5. After input data has been processed, the Action automatically redirects to location of the composite page, effectively switching from input phase back to render phase. Steps 1 through 3 are repeated, and an updated page is presented to the user. inline:action_component_title.gif == Component Configuration == - Defining configuration before creating a component seems backwards, but different configuration options affect component itself, so for the sake of this example let us first define the parameters composite page and the login component in {{{struts-config.xml}}} file. Do not forget to turn automatic validation off, otherwise an event handler will not be called if associated form bean failed validation. In Struts 1.4 event definitions are first-class elements of an action mapping: + Defining configuration before creating a component seems backwards, but different configuration options affect the component, so for the sake of this example let us first define the composite page and the login component in the {{{struts-config.xml}}} file. Do not forget to turn automatic validation off, otherwise if an associated form bean fails validation, an event handler in the Action will not be called. + + In Struts 1.4 event definitions are first-class elements of an action mapping: {{{<struts-config> @@ -45, +47 @@ </struts-config> }}} - Observe attributes and properties that are new for Struts 1.4: + Observe attributes and properties new for Struts 1.4: - * "component" attribute contains the name of a component. It identifies an action as a component manager, it is processed differently than a regular action or behavioral action. + * "component" attribute contains the name of a component. It identifies an action as a component manager. Such actions are handled differently than a regular action or a simple dispatch action. - * "view" attribute identifies a default view for a component. Must be a JSP page. Often consists from several subviews, in our case the Login Component has two subviews "Not Logged In" and "Logged In", they will be defined in JSP file. + * "view" attribute identifies a default view for a component. Must be a JSP page. Often consists from several subviews, in our case the Login Component has two subviews "notloggedin" and "loggedin". * "form" is just another name for "name" property - * "event" property allows to define request parameters as events, and corresponding method handlers. + * "event" property allows to define incoming events and corresponding method handlers. An event is just a request parameter. - In Struts 1.2.9 - 1.3.x Action class does not implement dispatching functionality, and action mapping does not allow to define events. It is recommended to use EventDispatchAction to handle incoming events, its events are configured through {{{parameter}}} attribute: + In Struts 1.2.9 - 1.3.x Action class does not implement dispatching functionality, and action mapping does not allow to define events. !EventDispatchAction class is the best choice to handle component events. The events are configured through {{{parameter}}} attribute: '''Struts 1.2.9, 1.3.x:''' {{{<struts-config> @@ -82, +84 @@ </struts-config> }}} - Of course, Struts 1.2.9, 1.3.x do not support new "component", "view", "form" and "event" properties. Use regular {{{forward}}} element to define a component view. Use {{{name}}} attribute to define associated form bean. + Of course, Struts 1.2.9, 1.3.x does not support new "component", "view", "form" and "event" properties. Use regular {{{forward}}} element to define component views. Use {{{name}}} attribute to define associated form bean. == Component Action == - With Struts 1.4 the action class is deceptively simple. It handles only two events, the corresponding handlers are called automatically by Action class. The location of component's view is defined in the action mapping, so render method is not needed. On the other hand, most non-trivial components need to process data before rendering themselves or to exchange data with other components. For these cases you can use render" method. Its default implementation does nothing. + With Struts 1.4 the component action class is deceptively simple. In our example it handles two events, the corresponding handlers are called automatically by Action class. The location of component's view is defined in the action mapping, so there is no need to return an {{{ActionForward}}} object pointing to a JSP file. On the other hand, most non-trivial components need to process data before rendering themselves or to exchange data with other components. For such cases you can use {{{render}}} method. Its default implementation does nothing. {{{ public class LoginAction extends Action { @@ -128, +130 @@ inputForm.setUsername(null); inputForm.setPassword(null); - // Remove dialog name from session, effectively logging out + // Remove user name from the session, effectively logging out request.getSession().removeAttribute("USER"); // Always return null. @@ -137, +139 @@ } }}} - In Struts 1.2.9 - 1.3.x Action class does not implement dispatching functionality, you need to extend a dispatching action. Use EventDispatchAction as the simplest and the most flexible. Another difference is that you need to specify an {{{ActionForward}}} object that points to a component view. You must do it in {{{unspecified}}} method or whatever method you selected as default in event definition. + In Struts 1.2.9 - 1.3.x Action class does not implement dispatching functionality, you need to extend a dispatching action. Use !EventDispatchAction as the simplest and the most flexible choice. Another difference is that you need to specify an {{{ActionForward}}} object that points to a component view. You must do it in {{{unspecified}}} method or whatever method you selected as default in event definition. - Using EventDispatchAction to dispatch events gets you only halfway, because there code that automatically distinguishes the address of a composite page and then redirects to it is not present in older Struts versions. You need an add-on library that contains this code. Then you need to call it from {{{execute}}} method of your action. '''TODO''' + Using !EventDispatchAction to handle incoming events gets you only halfway, because the code that automatically distinguishes the address of a composite page and then redirects to it is not present in older Struts versions. You need an add-on library that contains this code. Then you need to call it from {{{execute}}} method of your action. '''TODO''' '''Struts 1.2.9, 1.3.x:''' {{{ @@ -200, +202 @@ == Login And Logout Views == - The Login Component has two subviews, one for a non-logged-in user, another for a logged-in user. In this example views are defined in one JSP page. It is possible to define them in different JSP files, but in this case you will not be able to use {{{view}}} attribute of an action mapping, and you will have to explicitly forward to view locations in similar manner as Struts 1.3.x {{{unspecified}}} method does. + The Login Component has two subviews, one for a non-logged-in user, another for a logged-in user. In this example views are defined in one JSP file. It is possible to define them in different JSP files, but in this case you will not be able to use {{{view}}} attribute of an action mapping, and you will have to explicitly forward to view locations in a similar manner as with Struts 1.3.x. {{{ <%@ page contentType="text/xml;charset=UTF-8" language="java" %> @@ -251, +253 @@ == Composite Page == - Now we need to include the Login Component into a larger page (composite page). This is done with JSTL <c:import> tag. Do not use <jsp:include>, it may not work on some containers: + Now we need to include the Login Component into a larger page (composite page). This is done with JSTL <c:import> tag. Do not use <jsp:include>, it may not work in some containers: {{{<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> @@ -261, +263 @@ <p>This paragraph is defined directly in the parent page and should precede the content of login control.</p> - <c:import url="/loginintegrated.do" /> + <c:import url="/logincomponent.do" /> <p>This paragraph is defined directly in the parent page and should follow the content of login control.</p>