====== Java Struts from a PHP Perspective ====== Struts is a java framework for developing web applications. Struts is known for its [[pattern:Front Controller]] implementation and its centralized configuration file, but it provides several other capabilities as well. ===== Key struts concepts ===== 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 ==== An ''Action'' class in struts is an implementation of the [[pattern:Command]] 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 '''' 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) * ''mapping'' and ''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. ''NULL'' indicates that processing is complete. The [[HttpServletRequest]] and [[HttpServletResponse]] objects are not part of the struts framework. They are part of J2EE. 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. ==== Action Mapping ==== //The effort to classify the roles of an Action Mapper are nice, but realize that an Action Mapper object is actually a standardized [[pattern:Page Controller]]// The ''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 tag. (CONFUSION WARNING: '''' 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 '''' tag. === FrontController dispatch target === Every '''' 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 '''' 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. === Gateway Role === ActionMappings can be used to specify control logic to execute before passing control to another class. === Action Gateway === Only the '''' 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. === Request Gateway === === Action Context Cookie === The ''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 ''ActionMapping'' object. === Form Controller === Action Mappings implement various control flow logic for forms. The Form logic for the ''ActionMapping'' is specified by attributes in the '''' tag. === Security controller === An ''ActionMapping'' can require a certain security level before passing control. === Forwarding dictionary === ===== Struts Port ===== 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 [[pattern:Model View Controller]] for a discussion of Struts and MVC. See [[php:MVC Frameworks]] for a list of Struts Ports.