Struts is a java framework for developing web applications. Struts is known for its Front Controller implementation and its centralized configuration file, but it provides several other capabilities as well.
Struts is confusing for new users. This is mostly because of a series of very unfortunate naming choices (give the word action a rest). Objects in the framework and tags in the configuration file have the same names but different functions.
Action class in struts is an implementation of the Command Pattern pattern. Action commands perform a task on the users behalf. Actions are triggered by a user request to the web server which is mapped to a specific command object by the struts framework (guided by the configuration file.)
Actions are usually implemented by subclassing an
Action Class and adding an implementation of the execute method. The class name is registered using the type attribute of the
<action> tag in the centralized configuration file and struts takes care of instantiating Action objects and calling their execute method at appropriate times.
The workhorse of the action class is the execute method:
ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
form: the struts framework context in which the action is performed.
request: The Http request which triggered this action
response: An object for constructing an http response to this request
ActionForward(return value): Indicates which view or action should be performed following the current action.
NULLindicates that processing is complete.
In PHP, the superglobals $_GET, $_PUT, $_FILES, $_COOKIES, and $_SERVER contain the information that is accessed through the HttpServletRequest object in Java. The PHP analog of the HttpServletResponse class are functions such as echo, print, header(), and setcookie().
In Java, multiple requests are serviced from the same Action object instance. Each request has its own thread, but they all share the same memory space which means that the action objects must be thread safe. For this reason, the framework uses parameters and return values to pass information into and out of the action, avoiding unsafe global or class variables. In PHP, each requests is served out of its own address space. This allows PHP to use global state while processing requests.
PORTING PITFALL #1
The difference in threading and request servicing models between PHP and Java is an important consideration for those porting struts concepts to PHP. In PHP, it is unnecessary for the command methods to be thread safe. Thus the request and response parameters are unnecessary in a PHP port.
Implementing Java inspired wrappers for native PHP puts a needless burden on the experienced PHP programmer to learn Java Idioms. Requiring the use of java style request and response objects limits the ability for third party PHP libraries that use the native PHP idioms for request and response to integrate with the ported framework. re-packaging the native idioms needlessly adds a level of indirection and additional runtime overhead.
The effort to classify the roles of an Action Mapper are nice, but realize that an Action Mapper object is actually a standardized Page Controller
ActionMapping class in struts is a Jack-of-all-trades. This is generally not the sign of a good object oriented design. The ActionMapping object performs many different roles in the struts framework.
ActionMappings are a utility class used internally by the Struts framework. Application developers do not generally subclass or implement ActionMappings. Instead, they declare ActionMapping classes in the configuration file using the <action> tag. (CONFUSION WARNING:
<action> tags do not define action objects in Struts, they define ActionMapping objects.) The framework instantiates and calls the
ActionMapping objects as appropriate based on the
<action> tag corresponds to an
ActionMapping object instance.
The Front Controller has a catalog of
ActionMappings and resolves the url of a request into an instance of an
ActionMapping. The FrontController uses the path attribute of the
<action> tag to determine which
ActionMapping instance should be used for a specific request.
Once the proper
ActionMapping object instance is selected control is passed to it.
ActionMappings can be used to specify control logic to execute before passing control to another class.
<action> tags with the OPTIONAL type attribute actually refer to Action object instances. When the type attribute is specified, the ActionMapping Object servicing the request will call the execute method of the appropriate Action class.
In this role, the
ActionMapping acts as a gateway to the action, performing necessary control logic prior to executing an Action.
ActionMapping object passes itself as a parameter to its action’s execute method, representing the context in which the application is executed. The Action can make various call backs on the
Action Mappings implement various control flow logic for forms. The Form logic for the
ActionMapping is specified by attributes in the
ActionMapping can require a certain security level before passing control.
One difference between the Java based Struts and PHP is the way in which http request dispatch is acomplished. Struts uses an XML file to map http requests onto Java objects and PHP ports of Struts must also construct such a mapping. In Struts, the objects that represents this mapping are persistent in the java virtual machine between requests. In the PHP ports, no state is retained between requests. This means that the mapping is reparsed or reloaded on every request. This adds a per request processing overhead to using this FrontController pattern in PHP which does not exist in Java. (Actually, java pays for the overhead in RAM usage instead of CPU usage.)
See Model View Controller for a discussion of Struts and MVC.
See PHP MVC Frameworks for a list of Struts Ports.