Struts- Why? What? How?

Application architecture for web applications has been evolving over the past decade. The Model View Controller (MVC) architecture has, in recent times evolved to be the de facto architecture for most web applications. Earlier, application developers went through a phase of first developing the framework usually as a combination of JSP, Servlets and Value Objects) before writing the application itself. There was a strong need for a reusable framework incorporating industry best practices to form the basis for web application development. Struts does an effective job of providing the pre packaged framework.

In addition to being a framework for MVC, Struts provides the following features to ease the developer’s job.

a. Custom tag libraries
b. Message repository (ApplicationResources.properties)
c. Configurable user Input validation
d. Structured views using Tiles and Templates.
e. Reusable utility classes
f. Options for customizing all of the above specific needs

Struts can be used on any Servlet Engine that conforms to the Servlet 2.2 and JSP 1.1 Specification. It has been tested on most popular servers including WebSphere, Weblogic, Tomcat, iPlanet among others.

Struts essentially contains:

· A set of jar files
· A set of configuration files (conforming to the published DTDs)
These are to be included in the Application’s WAR file

The Application logic that developers write is in classes that extend base classes provided in the Struts jar files.
These are action classes and action forms.

MODEL VIEW CONTROLLER

Model: The model represents enterprise data and business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real world modeling techniques apply when defining the model.

View: The view renders the contents of a model. It accesses enterprise data through the model and specifies how that data should be presented. It is the view’s responsibility to maintain consistency in its presentation when the model changes. This can be achieved by using a push model, where the view registers itself with the model for change notifications, or a pull model, where the view is responsible for calling the model when it needs to retrieve the most current data.

Controller: The controller translates interactions with the view into actions to be performed on the model. In a stand-alone GUI client, user interactions could be button clicks or menu selections, whereas in a web application, they appear as GET and POST http requests. The actions performed on the model include activating business processes or changing the state of the model. Based on the user interactions and the outcome of the model actions, the controller responds by selecting an appropriate view. (This is configured in the struts-config.xml that sets the action servlet)

Struts implementation of MVC

Struts is pretty much a textbook implementation of MVC. The JSP is the view containing only display formatting. There is a single Servlet controller that services all requests and delegates requests to separate handler actions.
The form beans and java beans form the model part of the equation.

The process flow is described as follows:

The browser sends a request with information to be processed. The information delivered to the application comes in a “ form bean “ – a Java bean which maps that field to html controls on the view page. Struts populates the form bean with data automatically from information that has been entered by the user on the screen. Form bean data is available to the controller servlet and handler classes for processing.

The controller servlet does centralized processing that is common to all requests being serviced and then hands off control to individual handlers that do specific processing based on the actions being performed. The mapping of request URLs to Action handler classes is easily done using an XML configuration file struts-config.xml.

The handlers are tied to model components. They contain logic for interacting with java beans / EJBs that encapsulate business logic and interact with persistent storage. The handler then forwards control to the next appropriate view to be displayed to the user.

Business logic
Beans encapsulate the functional logic of the application. For small to medium sized applications they may be java beans or for larger applications EJBs. These beans would access a database using JDBC.

Struts-config.xml
Sample Struts Config entry

<struts-config>
	<form-beans>
		<form-bean name=”myform” type=”mypackage.MyForm” />
		<form-beans>
			<action-mappings>
				<action path="/welcome.do" type=”mypackage.MyAction” name="MyForm">
					<forward name="success" path="views.welcome" />
					<forward name="error" path="views.error" />
				</action>
			</action-mappings>
</struts-config>

In the struts-config file, form beans are defined. In the example, an instance “MyForm” is defined of type mypackage.MyForm. A form bean usually maps to an input view of the application, The form bean extended from the base Struts Action Form is to be coded by the developer in such a way that the fields of the form bean map to input html controls on the view.

The struts-config file also contains action mappings. The URLs of the applications are mapped one to one with a specific action to be performed. In the example “/welcome.do” URL pattern is mapped to “mypackage.MyAction” handler class and the “MyForm” form bean. Based on decision constructs inside the handler class, control may transfer to either one of the many views defined within action mapping.
Here, the handler classes may decide to show “welcome page” or the “error page” view based on program conditions.

Sample JSP content

Struts provide JSP custom tag libraries to automatically map html elements to form bean fields.

<html:form action=”logon.do”/>
User Name:<html:text property=”username”/>
	<html:submit/>
</html:form>

Here the username value entered into the HTML page is automatically populated into the username property of the MyForm bean.

Struts Custom Tag Libraries

Struts provides (among others) the following custom tag libraries to be used in JSP pages.
1. HTML
2. Bean
3. Logic

As described previously, HTML tags enchance the functionality of standard HTML controls. Input field types support checkboxes, hidden fields, password, radio buttons, reset buttons, select lists..
Eg.

<html:text property=”username”/>

Struts bean tags provide useful display mechanisms for bean values. For example


<bean:write name=”MyBean” property=”role”/>

prints the value of the bean property on the screen.


<bean:message property=”label.username”/>

prints the message from properties file for the key label.username
eg

<javascript>
func()
{
document.forms[0].taskbar.value =”<bean:message key=prompt.warning”/>
return false;
}
</javascript>

Struts logic tags provide useful decision constructs using which we could avoid, using java scriptlets within the JSP page.
For example

<logic:equal name=”MyBean” property=”role” value=”super”>
Hallo SuperUser
</logic:equal>
<%
String name=session.getAttribute(“name”);
if (name.equals(“super”))%>
Hallo SuperUser
<%}%>

Other logic tags include logic:notEqual, GreaterEqual, present, notPresent, iterate, empty, match, notMatch among others.

Application Resources

Messages are stored in a single central repository file- ApplicationResources.properties Both the view and the handler class have access to ApplicationResources.properties.
Any text displayed to the user would come from the properties file, instead of being hard coded in Java or JSP.
These could include:
1. JSP/ HTML Text Button Labels..
2. System messages displayed to the user.

ApplicationResources.properties introduces flexibility into the application in the sense that any changes to textual display content does not necessitate changing java / JSP code but just needs a simple change in the properties file.

A single entry in AppicationResources.properties can be modified at runtime to be used at multiple places.

For example:

IsRequired={0} is required

This message can be modified at runtime and the {0} can be substituted to generate these messages “Username is required” and “Password is required”..

The properties file can effectively be used as a database, to the effect that it can be queried to retrieve single message for display. The key of the message can be used to identify the message text.

Also this repository is flexible enough to account for multiple languages. For instance one could have two different repositories for English and German.
One would be able to switch between the two without any programmatic changes.

Struts Validation

The value addition that Struts brings to the table as regards input validation is flexibility.
Validation can be done using

a) Java Code validation
Java code can be written in the “validate” method of the form bean to validate user input. Here validation happens before control is passed to the handler class, hence validation is isolated from the code in the handler class. This kind of validation is usually used where more complex validation (besides required, mask …) is necessary.
b) Automatic validation using validation.xml
In Struts adding entries into validation.xml configuration file does automatic validation. This is particularly useful in cases where we have to enforce validation for simple rules like “required”, “format mask”, “date”, “numeric” or anything else that can be done by evaluation of regular expressions.

Struts-config.xml

Sample Validation.xml entry

<form name="MyForm">
	<field property="SSN" depends="required,mask">
		<msg name="mask" key="ssn.nine.digits.numeric" />
		<var>
			<var-name>mask</var-name>
			<var-value>^d{9}$</var-value>
		</var>
	</field>
</form>

This entry enforces nine digits numeric validation on the SSN property of the MyForm bean.
If the user does not enter anything in the SSN field of the input page, the “required” validation kicks in and a message “SSN is required” is displayed.

If the user enters an invalid SSN that does not fit the mask of 9 digit numeric digits as specified by the regular expression, then the message specified in ApplicationResources.properties corresponding to the key “ssn.nine.digits.numeric” is used for display.

This type of automatic validation can be used for

1. Client side JavaScript validation – Struts automatically generates client side JavaScript to popup a dialog with the message.
2. Server side validation -After the page is submitted, it is reloaded with the error message included.

Structured Views Using Tiles

JSP files (view) can be structured using Struts Tiles. With Tiles one can define a layout of JSP pages and use a layout across pages of an application. This helps in getting a consistent look and feel.
For instance, a header, footer or other component in a JSP page can be defined to be in a certain position of the layout. All the pages using the layout will then effectively position the component on the JSP correctly.

The structure of the views can be changed easily by changing the tiles-defs.xml conf file without modifying each of the individual JSP pages.

This design also encourages the use of JSP pages. It also decouples the physical filename of the JSP page from code by assigning to logical “tiles” names.

Sample tiles-defs.xml entry

<definition name="views.welcome" extends="default.Layout">
	<put name="title" value="/jsp/Title.jsp" />
	<put name="menu" value="/jsp/Welcome.jsp" />
</definition>

The Reverse Route Action to JSP

Lets say the action class interacted with the database and now has some information to be displayed in the JSP.
Case 1:
The information to be displayed in the next JSP is such that the page should be pre-filled (with value html elements).
In normal java programming you would use the “value=”, for each element.

<input type=”text” name=”somename” value=<%=somejavavalue%>”/>

Struts make it easier to do this.
Look at this part of the struts-config.xml entry:

<action path=”/option” type=”com.mattiz.struts.MyOptionAction” name=”MyOptionForm scope=”request”…..>

What struts does is that it keeps the form bean in the request object as an attribute. The attribute name is “MyOptionForm” in this case.

Now in the action class you do this:
com.mattiz.struts.MyOptionForm nextform=new MyOptionForm(),
set values into nextform and then
request.setAttribute(“MyOptionForm”, nextform)
Now when you forward to the next jsp, struts will read the form bean from request and automatically display contained values in the corresponding html elements of the page.

Note: In the above discussion, if you set scope=”session” then struts will keep the form bean as a session attribute instead of a request attribute.

Case 2:
The information is to be displayed as text display on the next JSP

In this case from the action class you can get some object into request (or session) and in the page you can set the object from the request and output it as you normally would.
In the JSP:

<%ValueObject vo=(ValueObject) request.getAttribute(“vo”);%>
…..
…..
<%=vo.getField();%>

This displays value.
You can achieve the same results as the above scriptlet using bean:write tag
It would look like this:

<bean:write name=”vo” property=”field” scope=”request”/>

About cuppajavamattiz
Matty Jacob - Avid technical blogger with interests in J2EE, Web Application Servers, Web frameworks, Open source libraries, Relational Databases, Web Services, Source control repositories, ETL, IDE Tools and related technologies.

Comments are closed.

%d bloggers like this: