| By Berndt Hamboeck | Article Rating: |
|
| March 1, 2002 12:00 AM EST | Reads: |
7,261 |
Struts is an open source initiative from the Jakarta Project written in Java. Sponsored by the Apache Software Foundation, the project's goal is to provide an open source framework that's useful for building Web applications with Java servlet and JavaServer Pages (JSP) technology. Struts encourages application architectures based on the Model-View-Controller (MVC) design paradigm.
In the MVC design pattern, application flow is mediated by a central controller that delegates requests to an appropriate handler. The handlers are tied to a Model and act as an adapter between the request and the Model. The Model represents or encapsulates an application’s business logic or state. Control is usually forwarded back through the Controller to the appropriate View. The forwarding can be determined by consulting a set of mappings, usually loaded from a database or configuration file. This provides a loose coupling between the View and Model that can make an application significantly easier to create and maintain.
The Model
The Model portion of an MVC-based system can be subdivided into concepts – the internal state of the system and the actions that can be taken to change that state. In grammatical terms, think about state information as nouns (things) and actions as verbs (changes to the state of those things).
Generally, your application represents the internal state of the system as a set of one or more JavaBeans, with properties that represent the details of the state. Depending on your application’s complexity, these beans may be self-contained (and somehow know how to save their state information persistently) or facades that know how to retrieve information from external sources (such as a database) when it’s requested. Entity Enterprise JavaBeans (EJBs) are also commonly used to represent internal state.
Large-scale applications will often represent the possible business logic actions in a system as methods that can be called on the beans that maintain the state information. For example, you might have a shopping cart bean stored in session scope for each current user, with properties that represent the current set of items the user has decided to purchase. This bean might also have a checkOut() method that authorizes the user’s credit card and sends the order to the warehouse to be picked up and shipped. Other systems represent the available actions separately, perhaps as session EJBs.
In some smaller scale applications the available actions might be embedded within the Action classes that are part of the Controller role. This is appropriate when the logic is very simple or where reuse of the business logic in other environments is not contemplated. The Struts framework supports any of these approaches, but recommends separating the business logic (what to do) from the role that Action classes play (deciding what to do).
The View
The View portion of a Struts-based application is generally constructed using JSP technology. JSP pages can contain static HTML (or XML) text called "template text," plus the ability to insert dynamic content based on the interpretation (at page request time) of special action tags. The JSP environment includes a set of standard action tags, such as <jsp:useBean>, whose purpose is described in the JSP specification. In addition, there’s a standard facility to define your own tags, which are organized into custom tag libraries.
Struts includes an extensive custom tag library that facilitates creating fully internationalized user interfaces that interact gracefully with ActionForm beans, which are part of the Model portion of the system.
In addition to JSP pages and the action and custom tags they contain, it’s often necessary for business objects to be able to render themselves in HTML (or XML), based on their current state at request time. The rendered output from such objects can be easily included in a resulting JSP page by using the <jsp:include> standard action tag.
The Controller
The Controller portion of the application focuses on receiving requests from the client (typically a user running a Web browser), deciding what business logic function is to be performed, and then delegating responsibility for producing the next phase of the user interface to an appropriate View component.
In Struts, the primary component of the Controller is a servlet of ActionServlet class. This servlet is configured by defining a set of mappings. Each mapping defines a path that’s matched against the request URI of the incoming request and the fully qualified class name of an Action class (a Java class extending the Action class) that’s responsible for performing the desired business logic and then dispatching control to the appropriate View component to create the response.
Struts also supports the ability to use ActionMapping classes that have additional properties beyond the standard ones required to operate the framework. This allows you to store additional information specific to your application and still utilize the remaining features of the framework. In addition, Struts lets you define logical "names" to forward control to so an action method can, for example, ask for the "loginfailure" page without knowing what the actual name of the corresponding JSP page is. These features greatly assist you in separating the control logic (what do I do next?) from the view logic (what is the name of the corresponding page?).
The primary functionality provided by Struts includes request dispatching, tag libraries to accelerate GUI development, internationalization, and automatic form population. Struts can be used in application development as the underlying architecture on which you develop your Web-based applications.
Installing Struts
The best place to download Struts is at
http://jakarta.apache.org/builds/jakarta-struts/release/v1.0. Installation is pretty easy; just unzip your downloaded file, jakarta-struts-1.0.zip, to c:\.
Our First Struts Application
A classic example of the Struts framework is the logon application. This example consists of the following Model-View-Controller (MVC) components.
Model
The model portion of the logon application consists of a subclass of org.apache.struts.action.Action that processes the request and handles all business logic (LogonAction.java). The model then passes control back to the view portion.
View
The view portion consists of three JSP pages:
- Input page for logon information (logon.jsp)
- Success page to acknowledge successful user login (success.jsp)
- Failure page (failure.jsp)
Controller
The controller for the logon application is the same controller used
for all Struts applications. It’s a servlet of type org.apache.struts.
action.ActionServlet.
Let’s Start
Create a directory to store your PowerJ workspace (C:\struts-login). In PowerJ, create a new workspace called struts-login (File —> New Workspace). Start EAServer 4.0 and make sure you have a working application server profile in PowerJ (Tools —> Application Server Profile).
Create the View Portion
The Logon Page
Create a new JSP 1.2 component (File —> New… from within Workspace View). Follow the wizard, entering in the following information and accepting the default when nothing is specified:
- Target name: logon
- JSP page name: logon
- Configure deployment options now: checked (default)
- Web application: struts-login
What Happens Here?
<%@ page language="java" %>
<%@ taglib
uri="/WEB-INF/struts-form.tld"
prefix="form" %><form:form action="logon.do">
Username: <form:text property="username" /><br>
Password: <form:password property="
password" /><br><form:submit value="Logon" />
</form:form>
First we import the Struts tag library, as we’ll use the form tags associated with it to map our input page to the model portion of the logon application:
<%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
Then we use the <struts:form> command from the tag library.
<form:form action="logon.do">Username: <form:text property="username" /><br>
Password: <form:password property="password" /><br>
<form:submit value="Logon" />
</form:form>
The form tag renders an HTML <form> element based on the specified attributes. It also associates all the fields within this form with a session-scoped form bean (LogonForm.java). This bean is used to provide initial values for all the input fields that have names matching the property names of the bean. If an appropriate bean is not found in the session, a new one will be created automatically.
The action parameter is the same as the action attribute in a normal form. In this example it points to the action (that we have yet to create) that will reside in action.xml under the logical name "logon".
The text tag renders an HTML <input> element of type "text". In this case the number of character positions to occupy on the browser’s screen has been specified as well. When this page is executed, the current value of the username property of the corresponding bean is the value returned by getUsername().
The password tag is used in a similar fashion. The difference is that the browser echoes asterisk characters instead of the input value as the user types the password.
Struts defines HTML tags for all the input fields that are shown Table 1.
To copy Struts files to your project, press the right-mouse button on your WAR (logonAll) and choose New Folder. Name it Web-Inf and create two new folders under it: classes and lib. Import (use RMB on the folder and click on Add File…) the file C:\jakarta-struts-1.0\lib\struts.jar into the lib folder, then import the tag library descriptor. A TLD is an XML document that describes a tag library. It contains information about the library and about each tag contained in the library. TLDs are used by a Web container to validate the tags and by JSP page development tools. Place the file C:\jakarta-struts-1.0\lib\struts-form.tld into the Web-Inf folder.
Tip: Enable Show All Files on the logonAll WAR target to see the JAR file (see Figure 2).
The Form Bean
Most Web developers build forms using the standard capabilities of HTML, such as the <input> tag. Users now expect interactive applications to have certain behaviors, and one of these expectations relates to error handling – if users make an error, the application should allow them to fix only what needs to be changed and not have to reenter any more information on the current page or form.
Fulfilling this expectation is tedious and cumbersome when coding with standard HTML and JSP pages. With Struts this can be done easily because of your form bean.
There’s a good example in the Struts documentation on how to handle errors during logins. We use our form bean only for storing the values entered by the form.
Create a new Java Classes Target (File —> New… from within Workspace View). Follow the wizard, entering the following information and accepting the default when nothing is specified:
- Depending target on this target: check logonAll
- Target name: logonClasses
Add C:\jakarta-struts-1.0\lib\struts.jar to the Build Options Classpath (see Figure 4). Create a new Standard Class (RMB logonClasses Target —> New… from within Workspace View). Follow the wizard, entering in the following information and accepting the default when nothing is specified:
- Package name: logon
- Class name: LogonForm
- Extends: ActionForm
The Success and Failure Page (logon/success.jsp)
The Success page displays a simple message advising the user of a successful logon; the Failure page displays a simple message advising the user of a failed logon.
Create another JSP page in your logon JSP 1.2 component by clicking on logon JSP 1.2 component, choosing New…, and naming it success.jsp; then copy and paste the code into the page. Repeat these steps for the failure.jsp page. Now you should have generated all necessary files for the View (see Figure 5).
<%@ page language="java" %>
<html>
<head>
<title>Successful Logon</title>
</head><body>
You have successfully logged on.
</body>
</html>
<%@ page language="java" %>
<html>
<head>
<title>Logon Failure</title>
</head><body>
You have incorrectly logged on.
</body>
</html>
Create the Model and the Controller
Now that you understand how to construct the View components of your application, it’s time to focus on the Model and Controller components. Struts includes a servlet that implements the primary function of mapping a request URI to an Action class. Therefore, your primary responsibilities related to the Controller are to write an Action class (i.e., an extension of the Action class) for each logical request that may be received. Write the action mapping configuration file (in XML) used to configure the controller servlet. Update the Web application deployment descriptor file (in XML) so your application can include the necessary Struts components.
Create the Action Class
The goal of an Action class is to process this request and then to return an ActionForward object that identifies the JSP page (if any) to forward control to generate the corresponding response.
Create a new Java Classes Target (RMB logonClasses Target —> New… from within Workspace View) in the logonClasses target:
- Package name: logon
- Class name: LogonAction
- Extends: Action
Create the Mapping File
To operate successfully, the Struts controller servlet needs to know several things about how each request URI should be mapped to an appropriate Action class. The required knowledge has been encapsulated in a Java interface named ActionMapping, and the most important properties are:
- Type: The fully qualified Java class name of the Action implementation class used by this mapping
- Name: The name of the form bean defined in the config file that this action will use
- Path: The request URI path that’s matched to select this mapping; (I’ll provide examples of how matching works later in the article)
- Unknown: Set to true if this action is configured as the application’s default to handle all requests not handled by another action; only one action can be defined as a default within a single application
- Validate: Set to true if the validate() method of the action associated with this mapping should be called
Create a new Any CodeFile (RMB Web-Inf folder —> New… from within Workspace View) in the logonAll target (see Listing 3).
First the form bean is defined. A basic bean of logon.LogonForm class is mapped to the logical name "logonForm". This name is used as a session or request attribute name for the form bean.
The "global-forwards" section is used to create logical name mappings for commonly used JSP pages. Each of these forwards is available through a call to your action mapping instance: actionMappingInstance.findForward("logicalName").
There is a mapping that matches the path /logon (because the example application uses extension mapping, the request URI you specify in a JSP page would end in /logon.do). When a request matching this path is received, an instance of the LogonAction class is created (the first time only) and used. The controller servlet will look for a session-scoped bean under key logonForm, creating and saving a bean of the specified class if needed.
The forward elements are used to take the appropriate action after verifying the username and password.
The Deployment Descriptor
A deployment descriptor is an XML text-based file with an .xml extension that describes a component’s deployment settings.
First we configure the tag library on the target logonAll (see Figure 6). We have to add the Struts-Controller Servlet to the deployment descriptor, which you can find in your struts.jar file. Within PowerJ you can’t edit the web.xml file directly, but PowerJ merges all XML files with the same DTD into the web.xml for deployment.
We have to create a file called myweb.xml, which must be placed into the Web-Inf folder. Create a new Any CodeFile (RMB Web-Inf folder —> New… from within Workspace View) in the logonAll target (see Listing 4).
Deploy and Test Your Application
Enter the same username and a password into http://localhost:8080/struts-login/logon.jsp and see how your success.jsp page is fired. If you enter different values, you’ll see your failure.jsp file.
Resources
Published March 1, 2002 Reads 7,261
Copyright © 2002 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Berndt Hamboeck
Berndt Hamboeck is a senior consultant for BHITCON (www.bhitcon.net). He's a CSI, SCAPC8, EASAC, SCJP2, and started his Sybase development using PB5. You can reach him under admin@bhitcon.net.
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- How PowerBuilder Got Its Groove Back
- The Cloud Has Cross-Border Ambitions
- Ulitzer Names The World's 30 Most Influential Virtualization Bloggers
- Ulitzer Named "New Media" Partner of Greatly Anticipated iStrategy Event in Berlin
- Risks and Enterprise Mobility?
- Steps for Success in Enterprise Mobility?
- Are Mobile Luddites Resisting Mobility?
- The Difference Between Web Hosting and Cloud Computing
- Sybase CTO to Speak at 4th International Cloud Computing Expo
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- Five Reasons to Choose a Private Cloud
- Seeding The Cloud: The Future of Data Management
- The Threat Behind the Firewall
- Economy Drives Adoption of Virtual Lab Technology
- Tips for Efficient PaaS Application Design
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- Where Are RIA Technologies Headed in 2008?
- PowerBuilder History - How Did It Evolve?
- The Top 250 Players in the Cloud Computing Ecosystem
- Custom Common Dialogs Using SetWindowsHookEx
- DDDW Tips and Tricks
- OLE - Extending the Capabilities of PowerBuilder
- DataWindow.NET How To: Data Entry Form
- Book Excerpt: Sybase Adaptive Server Anywhere
- Sybase ASE 12.5 Performance and Tuning
- Working with SOA & Web Services in PowerBuilder
- Office 2003 Toolbar: A New Look For Your Old PowerBuilder App
- Dynamically Creating DataWindow Objects































