Navigation Bar

Tuesday, September 15, 2009

Your first struts application : The Controller Components

LookupAction.java
In a struts application there are two main components that make up the controller.
org.apache.struts.action.ActionServlet and the org.apache.struts.action.Action classes. The ActionServlet is the controller component that handles client requests and determines which org.apache.struts.action.Action will process the request. This org.apache.struts.action.Action action class must be extended for each specialized function in your application. This class is where the application logic specific to that form resides.
In the getquote example, we have one basic requirement to process. i.e - look up the value of the submitted stock symbol. For this we create the LookupAction class which extends the org.apache.struts.action.Action class.  

If you will read the source code below for this class, it has two methods. The getQuote() method and the execute() method.   
The execute method has four parameters. Understanding these parameters is important to understand the flow and the control of the struts framework and its working.
ComponentDescription
ActionMappingThe ActionMapping class contains all the deployment information for a particular Action object. This class is used to determine where the results of the LookupAction will be sent once its processing is complete. It reads all this data from the struts-config configuration file
ActionFormThis is a JavaBean form whiich stores the input data or parameters from the corresponding View referencing the Action bean. In our example, the reference being passed to the LookupAction points to the instance of the LookupForm.
HttpServletRequestIt is a reference to the current HTTP request object. 
HttpServletResponseIt is a reference to the current HTTP response object.

After the execute method has completed its processing, it will return either a success or a failure. This value is passed to the ActionMapping.findForward() method which returns an ActionForward object. This ActionForward object is returned to the ActionServlet which forwards the request to the corresponding view, which will present the results of the action. 
The below line of code completes the steps described above.   
return (mapping.findForward(target));

A little deepdive into the struts framework.

Like any servlet as illustrated in previous examples,
 
  • Relationship between a Web Application and the ServletContext
  • Using Servlets to retrieve HTTP data from browser

  • the struts framework has an ActionServlet. This servlet is configured in the web.xml file for that project.
    This web.xml file contains a <servlet-mapping> that routes all URLs ending with *.do to the ActionServlet.  Thus the ActionServlet becomes a single point of entry for all framework requests for that web applicaion.
    When the servlet starts, and a request is sent from a jsp page, an instance of the ActionServlet servlet object is loaded on the web container. The init() method gets invoked which reads the struts-config.xml file.
    The ActionServlet true to its name, acts like a controller, and delegates all requests that come to it to the RequestProcessor. This RequestProcessor takes charge of the request lifecycle. From the struts-config.xml that has been loaded, it determines the correct ActionMapping based on the request URI. 
    It instantiates and invokes the appropriate Action class, passing the ActionMapping and ActionForm to its execute() method.
    After the action is completed the RequestProcessor forwards the response to another JSP or URL, based on the ActionForward specified in the struts-config configuration for that particular request.
    In this example, the RequestProcessor invokes LookupAction execute(). Here it checks if the form parameter has a value, and if so instantiates the LookupForm bean form where it gets the name of the request parameter symbol from the corresponding index.jsp page.
    Thus the Action class must be extended for each specific function in your application. This class has the main application logic for that particular action.  

    Below is a step by step description of a request-respone flow in struts
    A[User Request] --> B{Web.xml}
        B -- Matches *.do --> C[ActionServlet]
        C -- Reads --> D(struts-config.xml)
        C -- Uses mapping to find the the correct Action class from the action-mappings URI--> E[RequestProcessor]
        E -- Populates data into --> F[ActionForm Bean]
        E -- Invokes `execute()` method of the corresponding Action class--> G[Action Class]
        G -- Returns an --> H[ActionForward Object]
        H -- Contains path to --> I[JSP (View)]
        C -- Forwards to --> I
        I -- Renders content --> J[Response to User]
    


    package src;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.struts.action.Action;
    import org.apache.struts.action.ActionForm;
    import org.apache.struts.action.ActionForward;
    import org.apache.struts.action.ActionMapping;
    public class LookupAction extends Action {
        protected Double getQuote ( String symbol) {
            if ( symbol.equalsIgnoreCase ("SUNW") ) {
                return new Double (25.00);
            }
            return null;
        }
        public ActionForward execute (ActionMapping mapping,
                ActionForm form, 
                HttpServletRequest request,
                HttpServletResponse response )
                    throws IOException, ServletException {
                Double price = null;
                String target = new String ("success");
                if (form != null ) {
                    //Use the LookupForm to get the request parameters
                    LookupForm lookupForm = (LookupForm) form;
                    String symbol = lookupForm.getSymbol();
                    price = getQuote(symbol);
                }
                //Set the target to failure
                if (price == null) {
                    target = new String ("failure");
                }
                else {
                    request.setAttribute ("PRICE", price);
                }
                return (mapping.findForward(target));
        } //execute
    }  //Action

    To deploy this LookupAction, compile it and place the class file in
    <CATALINA_HOME>/webapps/getquote/WEB-INF/classes/src directory and add the following lines of code in the struts-config.xml file.
    <action-mappings>
    	<action path="/Lookup"
    		type="src.LookupAction"
    		name="lookupForm" >
    	<forward name="success" path="/quote.jsp" />
    	<forward name="failure" path="/index.jsp" />
    	</action>	
    </action-mappings>
    


    God's Word for the day
    A friend is not known in prosperity
      nor an enemy hidden in adversity
    One's enemies are friendly when one prospers
      but in adversity even one's enemies disappear
    Sirach 12:8-9

    Concerning Adultery 
    And if your right hand causes you to sin,
      cut it off and throw it away;
    It is better for you to lose one of your members
      than for your whole body to go into hell
    Mathew 5:30

    No comments:

    Post a Comment