Struts 2 | ModelDriven to handle Form Data


In struts2, values of request parameters(HTML form's fields) are mapped to matching properties of the action class . Struts populates the values come in Http Request to the variables having same name of input fields of the HTML form. When we want to persist the data received form request, it needs to be in model object that can be persisted by ORM framework like JPA or Hibernate. So if we are using the Action class to handle the values from form, we have to mark it as Entity for JPA/Hibernate to persist its data. Therefore using the action class as Entity class is not a best practice.

Struts2 provides another option to handle to form data. We can use separate Entity bean/Object to receive the form data rather than Action class. In terms of struts, it is called Model object. This is the same thing as Entity object in terms of JPA/Hibernate. In struts, we have to implement the ModelDriven interface that has the getModel method. This method returns the model object and properties of model object are populated with Form's Fields by struts framework. We need to follow the naming convention of HTML form fields and properties of model object to mapping the values properly.

package model;

public class Contact {
    String name;
    String email;
    long phone;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public long getPhone() {
        return phone;
    }

    public void setPhone(long phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "Contact [name=" + name + ", email=" + email + ", phone="
                + phone + "]";
    }

}
Class Contact is the simple model/entity class having the getter/setters for all properties. You can annotate this class as required for processing by JPA/Hibernate framework.

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

public class MyAction extends ActionSupport implements ModelDriven {

    model.Contact c = new model.Contact();

    public Object getModel() {
        System.out.println("getModel");
        return c;
    }

    public String execute() {
        System.out.println(c);
        return "success";
    }

}


In action class we are implementing ModelDriven interface and providing implementation of getModel that returns Contact model c. When user submits the form, all values from text fields are mapped to Contact object's properties and execute method print them. Bellow is the HTML page having three text fields. You can notice that name of the text fields and name of the properties of Contact class are same.
<html>
<body>
<h1>Test A file</h1>
<form action="processForm" method="post">
User Name: <input type="text" name="name"/><br/>
Email: <input type="text" name="email"/><br/>
Phone: <input type="text" name="phone"/><br/>
<input type="submit"/> 
</form>
</body>
</html>
Here is the struts.xml file that defins processForm action.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUB
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="default" namespace="/" extends="struts-default">
        <action name="processForm" class="MyAction">
            <result name="success">b.jsp</result>
            <result name="input">a.jsp</result>
        </action>
    </package>
</struts>

web.xml file

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  
  <filter>
    <filter-name>f</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>f</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>



Download Example


3 comments:

Anonymous said...

nice tutorial .!!

Anonymous said...

Thanks..
From this tutorial I solved My problem

Binh Thanh Nguyen said...

Thanks, nice post

Popular Posts