In a previous article I’ve explaned how to integrate the Hibernate framework in a Struts-MVC web application. Now I will show how to use Hibernate to implement the CRUD functionality for the Customer domain object.
Follow the main Struts-MVC objects that I will use:
– ActionForm: to maintains the session state for web application; ActionForm object is automatically populated on the server side with data entered from a form on the client side
– DispatchAction: to group a set of Customer related actions like create, update, read and delete (CRUD) into a single action called CutomerAction
– ActionForward, ActionMapping: to integrate Struts controller servlet’s functionality with the business logic component and the Velocity pages of Customer.
Create ActionForm object for the Customer
– CustomerForm
package com.demo.form; import org.apache.struts.action.ActionForm; public class CustomerForm extends ActionForm { private static final long serialVersionUID = 3L; private Long id; private String name; private String lastname; private String address; private String city; public CustomerForm() { // TODO Auto-generated constructor stub } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
Define the form bean in struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"> <struts-config> <!-- ================================================ Form Bean Definitions --> <form-beans> <form-bean name="customerForm" type="com.demo.form.CustomerForm" /> </form-beans> <!-- =========================================== Action Mapping Definitions --> <!-- A Velocity test --> <action-mappings> <action path="/testVelocity" forward="/velocityPage.vm" /> </action-mappings> </struts-config>
Now let’s see how to configure the Controller layer for the Customer using the “org.apache.struts.action” components. Create the CustomerAction class which extends the Struts DispatchAction. The CustomerAction class contains the action methods for the CRUD functionality.
– CustomerAction
package com.demo.action; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.actions.DispatchAction; import com.demo.domain.Customer; import com.demo.form.CustomerForm; import com.demo.hibernate.DAOFactory; import com.demo.persistence.CustomerDAO; public class CustomerAction extends DispatchAction { private Log log = LogFactory.getLog(this.getClass()); private DAOFactory factory = DAOFactory.instance(DAOFactory.HIBERNATE); /** * * Retrieve a list of Customer * * @param mapping * @param form * @param request * @param response * @return * @throws Exception */ public ActionForward multiRetrieve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception{ try { DAOFactory factory = DAOFactory.instance(DAOFactory.HIBERNATE); CustomerDAO CustomerDao = factory.getCustomerDAO(); List<?> customers = CustomerDao.findAll(); request.setAttribute("customerList", customers); } catch (Exception e) { log.error("customers not found", e); } return mapping.findForward("showMulti"); } /** * Retrieve a single Customer * * @param mapping * @param form * @param request * @param response * @return */ public ActionForward singleRetrieve ( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){ try { CustomerDAO cdao = factory.getCustomerDAO(); Customer customer = new Customer(); if (request.getParameter("id") != null) { customer = cdao.findById(new Long(request.getParameter("id")),true); } BeanUtils.copyProperties(form, customer); request.setAttribute("customer", customer); } catch (Exception e) { e.printStackTrace(); log.error(e); } return mapping.findForward("showSingle"); } /** * * Create or update a Customer * * @param mapping * @param form * @param request * @param response * @return */ public ActionForward createOrUpdate (ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) { try { CustomerDAO cdao = factory.getCustomerDAO(); Customer customer = new Customer(); CustomerForm customerForm = (CustomerForm) form; BeanUtils.copyProperties(customer, customerForm); cdao.makePersistent(customer); request.setAttribute("id", customer.getId()); } catch (Exception e) { e.printStackTrace(); log.error(e); } return mapping.findForward("successCreateOrUpdate"); } /** * * Delete a Customer * * @param mapping * @param form * @param request * @param response * @return */ public ActionForward delete ( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){ try { CustomerDAO cdao = factory.getCustomerDAO(); Customer customer = cdao.findById(new Long(request.getParameter("id")),true); cdao.makeTransient(customer); } catch (Exception e) { e.printStackTrace(); log.error(e); } return mapping.findForward("successDelete"); } }
Configure the Customer action mapping in the struts-config.xml. Note the use of parameter=”action” definition used to specify the ActionForward which is called in the http request (i.e. http://localhost:8080/demo/customers.do?action=multiRetrieve)
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"> <struts-config> <!-- ================================================ Form Bean Definitions --> <form-beans> <form-bean name="customerForm" type="com.demo.form.CustomerForm" /> </form-beans> <!-- =========================================== Action Mapping Definitions --> <!-- A Velocity test --> <action-mappings> <action path="/testVelocity" forward="/velocityPage.vm" /> <!-- Customer Actions --> <action parameter="action" path="/customers" type="com.demo.action.CustomerAction" scope="request" name="customerForm"> <forward name="showMulti" path="/pages/customers.vm" /> <forward name="showSingle" path="/pages/customer.vm" /> <forward name="successCreateOrUpdate" redirect="true" path="/customers.do?action=multiRetrieve" /> <forward name="successDelete" redirect="true" path="/customers.do?action=multiRetrieve" /> </action> </action-mappings> </struts-config>
We now proceed to the configuration of the View layer using the Velocity template engine. For this we must create a page to show a list of Customers and a second page to read and update an existing Customer (or to create a new one).
– WebContent/pages/customers.vm
<html> <haed> <title></title> </haed> <body> <h5 class="titoloElenco"> CUSTOMER LIST</h5> <div align="center"> <table class="tabellaElenco"> <tr align="right"> <td colspan="6"> <a href="./customers.do?action=singleRetrieve">+ Create New</a> </td> </tr> </table> <table class="tabellaElenco"> <thead > <tr > <th >Name</th> <th >Lastname</th> <th >Address</th> <th >City</th> <th> </th> <th> </th> </tr> </thead> #foreach($Customers in $customerList) <tr> <td #alternateColorRows()>$!Customers.name</td> <td #alternateColorRows()>$!Customers.lastname</td> <td #alternateColorRows()>$!Customers.address</td> <td #alternateColorRows()>$!Customers.city</td> <td #alternateColorRows()><a href="./customers.do?action=singleRetrieve&id=$Customers.id">Update</a></td> <td #alternateColorRows()><a href="./customers.do?action=delete&id=$Customers.id">Delete</a></td> </tr> #end <tr align="left"> <td colspan="6"> </td> </tr> </table> </div> </body> </html>
– WebContent/pages/customer.vm
<body> <div class="ritorna"><a href="./customers.do?action=multiRetrieve">Back to Customer List</a> </div> <h5 class="titoloElenco"> Customer Create or Update </h5><br><br> <div align="center"> <table class="tabellaElenco"> <form id="customerForm" name="customerForm" action="./customers.do?action=createOrUpdate" method="post"> <input type="hidden" id="id" name="id" value="$!customerForm.id"> <!--<tr><td>$!customerForm.id </td></tr>--> <tr><td style="background:#EFF1FF;" ><h5>Name</h5></td> <td><input type="text" name="name" value="$!customerForm.name" ></td> <td style="background:#EFF1FF;"><h5>Lastname</h5></td> <td><input type="text" name="lastname" value="$!customerForm.lastname"></td> </tr><tr><td> </td><td> </td></tr> <tr><td style="background:#EFF1FF;"><h5>Address</h5></td> <td><input name="address" value="$!customerForm.address"></td> <td style="background:#EFF1FF;"><h5>City</h5></td> <td><input type="text" name="city" value="$!customerForm.city" ></td> </tr> <tr align="right"> <td colspan="6"><input type="submit" name="Save" value="Save"/></td> </tr> </form> </table> </div> </body>
Here the project layout