Friday, March 6, 2009

Struts 2

I am back after a long time with Struts 2 framework. Struts 1.x has been quite old and I never thought it was necessary to write about it as it always has enough tutorials in the net. But with the latest struts 2 framework, I have tried few things and came up with this blog.

Without any hesitation, just download the struts2-blank project and there you have everything required to start with.

Most of the information that is required for starting with struts 2 can be obtained from the official documentation of struts 2

Before you start with some real development, there are some notable differences between Struts 1.x and Struts2
If you have not use struts 1.x earlier, well and good for you because anyways the basic concepts on which struts 2 is built are quite different.

First of all There are no more formbeans. But do not wonder where you'll capture your form data, it all resides in your Action class. You can define all the attributes of your forms in Action class itself and framework will take care of populating them to and fro.
Action Class:
Now when I speak of Action classes, these are nothing but POJOs. The new framework does not need you to extend to class org.apache.struts.action.Action. But since this is a POJO, you cannot directly access the request or session object. Remember in old version these were provided by the framework through super Action class.

But dont be frowned, you can still access everything, with a little efforts. Struts 2 heavily uses Dependency Injection. That is, it will provide you with the stuff if you need, you dont have to get them. And there are interceptors for this. In our case, if you need a request object, just implement org.apache.struts2.interceptor.RequestAware; and for session object, implement org.apache.struts2.interceptor.SessionAware.
Implementing those two interfaces will let the framework know that you need this objects and the framework would inject the respective objects. So there you go, ready with an Action class.

Let's see a simple action class for login:

package mypkg;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.SessionAware;

import com.myapp.delegate.BusinessDelegate;
import com.myapp.vo.UserInfoVO;
import com.myapp.web.UserInfo;

/**
* Sample Login Action Class in Struts 2.
*
* @author Husain Basrawala
*/

public class LoginAction implements SessionAware {

private static Log logger = LogFactory.getLog(LoginAction.class);

// Form attributes
private String username = null;
private String password = null;

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;
}

// Map representing the Session object

private Map session = null;

public void setSession(Map session_) {
this.session = session_;
}

/**
* Execute method called on action.
*/
public String execute() throws Exception {
session.put("PROCESS_ID", "ABC");

BusinessDelegate delegate = new BusinessDelegate();
UserInfoVO userInfoVO = delegate.getUserInfo(username);

UserInfo userInfo = new UserInfo();
userInfo.setCode(userInfoVO.getCode());
userInfo.setName(userInfoVO.getName());
userInfo.setLevel(userInfoVO.getLevel());
session.put("USER_INFO", userInfo);
return SUCCESS;
}

/**
*
* Before calling each action method, framework looks for a validate method
* in the class.
*
* The validate mehod should follow a naming convention such as
* validateMethodName()
*
* or doValidateMethodName.
*
* The framework will call the validate method and if it does not add any
*
* error using addActionError then only the action method is called.
*
*/
public void validateExecute() throws BaseException {

if (FWUtilities.isBlank(username)) {
addFieldError("username", "username " + getText("error.required"));
return;
}

if (FWUtilities.isBlank(password)) {
addFieldError("password", "password " + getText("error.required"));
return;
}

BusinessDelegate delegate = new BusinessDelegate();
if (!delegate.isUserAuthentic(username, password)) {
addActionError(getText("error.invalidlogin"));
logger.debug("Invalid user login tried");
}
}

public String load() throws Exception {
return SUCCESS;
}
}