Sunday, February 22, 2009

Using Model Classes With Actions

This blog post intends to answer the following questions :-
  1. How to use the Prepareable and Model Driven interface in Struts 2?
  2. How to store data entered in a struts 2 form in a separate class instead of storing it in the Action class itself?
  3. How to use a POJO to store data entered by the user?
To begin with, lets first describe a POJO. POJO is an acronym for Plain Old Java Object. A POJO mainly consists of a large number of getter and setter method, thereby it can also be used as a JavaBean.

My motive is to store the data that is posted by the user via a form element in a POJO. My Action class is requred to store all the data entered in the form in the POJO on my begalf. And to receive this service I have to just add a few methods to my Action class.

In the following code example, a user enters his name and age as user details. This information reaches the Action class. These user details have to be stored in a JavaBean class called UserDetails. And all of this stuff is supposed to happen automatically instead of me having to call each setter method from the execute method.

Here is how I do it :-

UserDetails.java
------Start Of Source Code------
package user;

public class UserDetails
{
String name;
int age;

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
------End Of Source Code------


Register.java
------Start Of Source Code------
package user;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.ModelDriven;

public class Register extends ActionSupport implements ModelDriven, Preparable{

UserDetails user;

public void prepare()
{
user=new UserDetails();
}

public UserDetails getModel()
{
return user;
}

public String execute() throws Exception{
if(user.getName().equals("") || user.getName()== null || user.getAge()== 0){
return ERROR;
}
else{
return SUCCESS;
}
}
}
------End Of Source Code------


Struts.xml(Snippet)
------Start Of Source Code------
<action name="registerUser" class="user.Register">
<result name="success">/registrationSuccessful.jsp</result>
<result name="error">/error.jsp</result>
<result name="input">/error.jsp</result>
</action>
------End Of Source Code------

Explanation :-
In the above code, UserDetails is called the model class, Register is my action class. All of the task is done for us by the interceptors. All that we need to do is to initially prepare the userDetails object and then make it available to the Struts interceptor to call its setter methods. The preparable interface allows us to take any action before the setters are called. Hence it its the appropriate place to initialize the userDetails instance variable. The ModelDriven interface provides a means to inform the framework about the object whose setter methods need to be called and hence be used as the model. It does this by returning a model object (the object that will store the data entered by the user) from the getModel method.
So the task is easily handled. Initialize the object in the prepare method if you haven'd done so already. Then return the object to framework through the getModel method. Cheers!

Happy Programming ;)

Signing Off
Ryan

No comments: