JavaData & JavaExploring the Struts 2 Web Application Framework

Exploring the Struts 2 Web Application Framework

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Web applications are inherently multi-layered. There are layers for presentation, business logic, and data persistence. It is perfectly suited for MVC (Model-View-Controller) layered architecture. Struts is also a MVC-based framework, but it basically seats in the presentation layer, responsible for furnishing a response in the browser. Struts, however, does more than that, but this is its basic functionality. It is an MVC framework because the architecture is in coherence with the generic MVC pattern, although working in the presentation layer. The communication between layers is established by a data transfer object. Business logic is rarely written in an Action class, which is the core of the Struts framework. While exploring these factors, the article will go hands-on in one key area: on a different approach to creating Action classes in Struts 2.

Key Features

Struts 2 is revamped with some of the excellent features that developers have been yearning for in a framework. See the comparison: Struts Vs Struts 2.

The marked features for Struts 2 are as follows:

  • Incorporation of a wide range of view technologies within the umbrella, such as velocity, freemarker, JSP, and so forth.
  • The conversion of values from string based for field to object or any other primitive types is automatic. There is no need for explicit conversion code in an Action class.
  • The declarative architecture using annotation helps in merging a configuration closer to the Action class.
  • Reduced burden of configuration. The principle of convention over configuration is implemented to a great extent.
  • The support for Ajax is a huge plus. This is particularly helpful in making asynchronous requests. Data transaction can be streamlined, improving performance considerably.
  • Struts 2 uses dependency injection to collaborate action with components.
  • Struts 2’s behavior is open to the plug-in enhancement
  • There is ample support for themes, templates, and various tags like UI tags, Data tags, Control tags, and so on.
  • Struts 2 supports integration of other frameworks as well such as Hibernate, Spring, and the like.

Struts 2 has considerably simplified the creation of Action classes with some convenient support library classes. Some of them are given in the following sections.

POJO as Action

Action is the core component for requesting processing logic. It acts as an intermediary of data transfer between the request and viewing the component. Any POJO can act as an Action class. For example, the following is a valid implementation of action, without any need to implement a library interface or extend any class.

package org.mano.action;

public class LoginAction{
   private String username;
   private String password;

   //...getters and setters

   public String execute(){
      if(getUsername().equals("user1") &&
            getPassword().equals("pass"))
         return "success";
      return "login";

   }
}

And the struts.xml configuration for the preceding Action class is as follows:

<package name="login" namespace="/" extends="struts-default">
   <action name="login" class="org.mano.action.LoginAction">
      <result name="success">/home.jsp</result>
      <result name="login">/login.jsp</result>
   </action>
</package>

Implementing an Action Interface

An Action interface provides string-based return values as a constant and a default execute() method. This interface is optional and can be implemented to modify the Action class in the following manner:

package org.mano.action;

public class LoginAction implements Action{
   private String username;
   private String password;

   //...getters and setters

   public String execute(){
      if(getUsername().equals("user1") &&
             getPassword().equals("pass"))
         return SUCCESS;
      return LOGIN;
   }
}

The Action interface is defined as follows:

package com.opensymphony.xwork2;

public interface Action {
   public static final String ERROR = "error";
   public static final String INPUT = "input";
   public static final String LOGIN = "login";
   public static final String NONE = "none";
   public static final String SUCCESS = "success";

   public String execute();
}

ActionSupport Class

The ActionSupport class is a concrete implementation of the Action interface and provides a default implementation of the execute() method. We can further modify LoginAction as follows:

package org.mano.action;

import org.apache.commons.lang.StringUtils;
import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport{

   private String username;
   private String password;

   //... getters and setter, username, password

   public void validate(){
      if(StringUtils.isEmpty(username)){
         addFieldError("username",
            "User name cannot be empty.");
      }
      if(StringUtils.isEmpty(password)){
         addFieldError("password",
            "Password cannot be empty.");
      }
   }

   public String execute(){
      if(getUsername().equals("user1") &&
            getPassword().equals("pass"))
         return SUCCESS;
      return LOGIN;
   }
}

The validate() method can be used to verify user input from a string-based form in a JSP file.

<s:form action="login">
   <s:textfield label="User Name" key="username" />
   <s:password label="Password" key="password" />
   <s:submit/>
</s:form>

Model-driven ActionSupport Class

We can further modify the Action class to use a model driven-feature. In such a case, the fields in the JSP form are automatically mapped with the model class. For example. let the model class for the User be as follows:

package org.mano.model;

public class User {
   private String username;
   private String password;
   public String getUsername() {
      return username;
   }
   public void setUsername(String username) {
      this.username = username;
   }
   public String getPassword() {
      return password;
   }
   public void setPassword(String password) {
      this.password = password;
   }
}

We can use this model class in LoginAction in the following manner.

package org.mano.action;

import org.apache.commons.lang.StringUtils;
import org.mano.model.User;
import org.mano.service.LoginService;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class LoginAction extends ActionSupport
      implements ModelDriven<User>{
   private User user=new User();
   public void validate(){
      if(StringUtils.isEmpty(user.getUsername())){
         addFieldError("username",
            "User name cannot be empty.");
      }
      if(StringUtils.isEmpty(user.getPassword())){
         addFieldError("password",
            "Password cannot be empty.");
      }
   }

   public String execute(){
      LoginService service=new LoginService();
      if(service.authenticateUser(user))
         return SUCCESS;
      return LOGIN; 
   }

   public User getUser() {
      return user;
   }

   public void setUser(User user) {
      this.user = user;
   }

   @Override
   public User getModel() {
      return user;
   }
}

The LoginService provides the business logic for the login.

package org.mano.service;

import org.mano.model.User;

public class LoginService {
   public boolean authenticateUser(User user){
      if(user.getUsername().equals("admin") &&
               user.getPassword().equals("admin"))
            return true;
         return false;
   }

}

Note that the key property of the Struts tag in the JSP form automatically maps to the model object declared within the LoginAction class. The responsibility of this implicit mapping rests on the getModel() method overridden from the ModelDriven interface.

   <body>
   <s:form action="login">
      <s:textfield label="User Name"
         key="username" />
      <s:password label="Password"
         key="password" />
      <s:submit/>
   </s:form>
   </body>

Conclusion

Apache Struts is Java’s veteran web application framework, still is in use in many major commercial applications. Apache Struts is a pioneer in the Web application framework that garnered an active interest among the community and inspired many a modern framework. The Action class is the primary concept one must have to begin with even the simplest program in the Struts framework. The article tried to give a glimpse of that specific area, with considerable hands-on detail.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories