Introduction to Struts Framework

Struts is an application framework for developing Java EE web applications. This is an open- source framework and was originally developed by Craig McClanahan and donated to Apache. Fundamentally, it uses and extends Java servlet API and supports Model-View-Controller (MVC) architecture. It allows us to create flexible, extensible, and maintainable large web applications based on standard technologies, such as Java servlets, JSP, JavaBeans, resource bundles, and XML.

1. Basic Idea

In a Java EE-based web application, a client usually submits data to the server using the HTML form. These data are then handed over to a servlet or a Java Server Page, which processes them, typically interacts with the database, and finally processes the HTML output that is sent to the client. Since servlet as well as JSP technologies mix application logic with the presentation, they are inadequate for large web projects.

The primary task of struts is to separate application logic that interacts with the database, called model from HTML pages that are sent to the client, called view and instance that passes information between model and view, called controller. For this purpose, struts provide a controller as a servlet, called ActionServiet, and allows the writing of templates for the presentation (view), typically in terms of JSP. This special servlet acts as a switchboard to route requests from clients to the appropriate server page. This simple idea makes web applications much easier to design, develop, and maintain. Figure 26.10 describes the struts framework.

That was a high-level description of the struts framework. Let us now discuss the framework technically in more detail.

Every web application has an associated XML file (wEB-iNF/web.xmi) called deployment descriptor. This file must be configured by the web application developer. The deployment descriptor file specifies the configuration of the web application such as servlet mapping, parameter to those servlets, welcome pages, etc. This web.xmi file is first configured to forward [Figure 26.10:] all requests with a specified pattern (usually *.do) to the struts framework’s ActionServiet using the following entry:

<servlet>

<servlet-name>action</servlet-name>

<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

<init-param>

<param-name>config</param-name>

<param-value>/WEB-INF/struts-config.xml</param-value>

</init-param>

<init-param>

<param-name>debug</param-name>

<param-value>2</param-value>

</init-param>

<init-param>

<param-name>detail</param-name>

<param-value>2</param-value>

</init-param>

<load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>action</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>

If you use an IDE such as NetBeans, these entries are automatically inserted. The web.xml file also specifies one or more configuration XML file (struts-config.xmi) that the ActionServiet will consult. This ActionServiet performs switching functions as mentioned earlier.

Suppose we are developing a web application using /myapp as a location relative to the server’s document root. In the struts-config.xmi file, we associate paths with the controller components called Action classes. The following is an example:

<action-mappings>

<action name=”LoginForm” path=”/login” scope=”request”

type=”com.myapp.struts.LoginAction”validate=”false”>

</action>

</action-mappings>

It specifies that the ActionServiet should invoke the controller component com.myapp.struts. LoginAction for the URL http://myhost/myapp/iogin.do. We also give a name to this association (“LoginForm” in our case) to refer to it further. Note that the web.xmi file specified that for the * .do pattern URL, ActionServiet should be invoked by the web container. So, the .do in this URL causes the web container to invoke ActionServiet of the struts framework. This ActionServiet consults the struts-config.xmi file and sees the path “login” and invokes LoginAction. The form data are temporarily stored in an ActionForm type bean. The developer has to write this bean by extending the ActionForm class explicitly. Action and ActionForm are bound using the name property of the <form-bean> tag. The following is an example:

<form-beans>

<form-bean name=”LoginForm” type=”com.myapp.struts.LoginForm”/>

</form-beans>

This “LoginForm” is the name of the action defined earlier and com.myapp.struts.LoginForm is the ActionForm bean.

For each Action, we can specify the names of the resulting page(s) that has(ve) to be sent to the client as a result of that action. There can be more than one view as the result of an action. Typically, there are at least two: one for “success” and one for “failure”. This is accomplished by returning a string from the execute() method of Action to the ActionServiet.

The action form, in turn, can retrieve data sent by the client from ActionForm bean. The following example illustrates this:

public class LoginAction extends org.apache.struts.action.Action {

/* forward name=”success” path=”” */

private final static String SUCCESS = ”success1”;

/* forward name=”failure” path=”” */

private final static String FAILURE = failure”;

/**

* This is the action called from the Struts framework.
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request.
* @param request The HTTP Request we are processing.
* @param response The HTTP Response we are processing.
* @throws java.lang.Exception
* @return
*/

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

// extract user data

LoginForm formBean = (LoginForm) form;

String name = formBean.getName();

String email = formBean.getEmail();

// perform validation

if ((name == null) || // name parameter does not exist

email == null || // email parameter does not exist

name.equals(””) ||  // name parameter is empty

email.indexOf(”@”) == -1){  

// email lacks ‘@’

formBean.setError();

return mapping.findForward(FAILURE);

}

return mapping.findForward(SUCCESS);

}

}

The parameter mapping in the execute() method refers to the ActionServiet and form refers to the associated ActionForm bean. The Action (the controller component) reports back to the ActionServiet using words like “success”, “failure”, “ready”, “OK”, “UserError”, etc. We specify corresponding view pages in the configuration file as follows:

<action name=”LoginForm” path=”/login” scope=”request”

type=”com.myapp.struts.LoginAction” validate=”false”>

<forward name=”success” path=”/success.jsp”/>

forward name=”failure” path=”/login.jsp”/>

</action>

The ActionServiet knows from the configuration file where to forward and what to show as a result. This has the added advantage of reconfiguration of the view layer by simply editing the XML configuration file.

The ActionForm beans can be validated ensuring that the user provides valid data in the form. The validation can be carried out on a per-session basis. It allows forms to span multiple pages of the View and Actions in the Controller.

Since the framework works on the server side, the client’s view has to be composed at the server before sending it to the client. Typically, some sort of server-side technology such as JSP, Velocity, and XSLT is used for the view layer. Simple HTML files may be used to compose client’s view. However, they cannot provide full advantage of all the dynamic features.

Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.

Leave a Reply

Your email address will not be published. Required fields are marked *