Showing posts with label J2EE. Show all posts
Showing posts with label J2EE. Show all posts

Sep 1, 2012

Form-based File Upload in J2EE Web Application Part 1

Many times we may have a file upload control on view asking user to upload a file or an image from local machine. HTML provides  a file control to upload a file. But on server side, we need to write a code to save it on a file server.

In J2EE, file upload functionality can be best achieved using Commons File Upload. A file upload request comprises an ordered list of items that are encoded according to RFC-1867. FileUpload can parse such a request and provide your application with a list of the individual uploaded items. Each such item implements the FileItem interface, regardless of its underlying implementation.

Each file item has a number of properties that might be of interest for your application. For example, every item has a name and a content type, and can provide an InputStream to access its data. On the other hand, you may need to process items differently, depending upon whether the item is a regular form field - that is, the data came from an ordinary text box or similar HTML field - or an uploaded file. The FileItem interface provides the methods to make such a determination, and to access the data in the most appropriate manner.

Before you can work with the uploaded items, of course, you need to parse the request itself. Ensuring that the request is actually a file upload request is straightforward, but FileUpload makes it simplicity itself, by providing a static method to do just that.

Let's make a very simple application to upload a file using JSP/Servlets as shown in following image.

Prerequisites


For this tutorial, we will need the following tools: (The older or newer version should also works). Moreover, basic Java knowledge is assumed.

  1. Eclipse IDE for Java EE Developers
  2. Apache Tomcat v6 or later
  3. Apache Commons IO 
  4. Apache Commons File Upload
Apache commons IO and File Upload jars has to be put in your web application lib folder. Following is the folder structure for this example.


Create a View using JSP


The view includes a simple file upload control with submit button. Following is the code:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

<form action="upload.do" method="post" enctype="multipart/form-data">
 Select file to upload: <input type="file" name="selectFile" /> <br />
 <input type="submit"> 
</form>


</body>
</html> 

 

Creating a Controller 

Controller will receive the multipart request. It will save the file at folder location configured in context parameters of the web application. It also creates a map of regular form parameters if any. We dont have any regular form parameter in this example. But that's put for your reference only.

package org.avid.upload.controller;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * @author Jay Rajani
 * 
 * Servlet implementation class UploadController
 */
public class UploadController extends HttpServlet {
 private static final long serialVersionUID = 1L;
 
 private String folderLocation = null; 
 
 @Override
 public void init() throws ServletException {
  super.init();
  this.folderLocation = getServletContext().getInitParameter("UPLOAD_FOLDER");
 }

 /**
  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  
  HashMap<String, String> formParams = new HashMap<String, String>();
  
  // Check that we have a file upload request
  boolean isMultipart = ServletFileUpload.isMultipartContent(request);
  
  try{
   if (isMultipart){
    
    // Create a factory for disk-based file items
    FileItemFactory factory = new DiskFileItemFactory();

    // Create a new file upload handler
    ServletFileUpload upload = new ServletFileUpload(factory);

    // Parse the request
    List<FileItem> items = upload.parseRequest(request);
    
    // Process the uploaded items
    Iterator<FileItem> iter = items.iterator();
    while (iter.hasNext()) {
        FileItem item = (FileItem) iter.next();

        if (item.isFormField()) {
         
         // Process a regular form field
         formParams.put(item.getFieldName(), item.getString());
        } else {
         
         // Process a file upload
         String fileName = item.getName();
         
         File uploadedFile = new File(folderLocation+File.separator+fileName);
            item.write(uploadedFile);
        }
    }
   }
  }catch(FileUploadException fue){
   fue.printStackTrace();
   throw new ServletException(fue.getMessage());
  }catch(Exception e){
   e.printStackTrace();
   throw new ServletException(e.getMessage());
  }
 }

}


Deployment Descriptor


Here is the snippet of final deployment descriptor.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 <context-param>
  <param-name>UPLOAD_FOLDER</param-name>
  <param-value>E:/temp</param-value>
 </context-param>
 
 <display-name>FileUpload</display-name>
 
 <servlet>
  <description>
  </description>
  <display-name>UploadController</display-name>
  <servlet-name>UploadController</servlet-name>
  <servlet-class>
  org.avid.upload.controller.UploadController</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>UploadController</servlet-name>
  <url-pattern>/upload.do</url-pattern>
 </servlet-mapping>

</web-app>

The code will save the file to location specified in web.xml. It can be a local folder or shared folder or ftp location depending on your requirement.

Aug 28, 2012

Step by step guide - Developing a MVC application using J2EE and MySQL


In this tutorial, we will create a simple J2EE application that performs CRUD (Create Read Update Delete) operations for User Management using Jsp, Servlet and MySQL.


Prerequisites


For this tutorial, we will need the following tools: (The older or newer version should also works). Moreover, basic Java knowledge is assumed.


  1. Eclipse IDE for Java EE Developers
  2. Apache Tomcat v6 or later
  3. MySQL Community Server and MySQL Workbench (GUI Tool)
  4. MySQL Connector for Java
  5. jstl.jar and standard.jar
You can get the required jars from your Tomcat. Check in this directory : (your tomcat directory)—>apache-tomcat-7.0.26-windows-x86—>apache-tomcat-7.0.26—>webapps—>examples—>WEB-INF—>lib

I will tell you where you should put these jars later.

jQuery for javascript capability. In this case, we only use it for the datepicker component

Create the database


First, lets create the database and table for User using the following SQL scripts:

create database UserDB;
use UserDB;
grant all on UserDB.* to 'admin'@'localhost' identified by 'test';

CREATE TABLE UserDB.`users` (
  `userid` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) DEFAULT NULL,
  `lastname` varchar(45) DEFAULT NULL,
  `dob` date DEFAULT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8


Setting up Eclipse and Tomcat


Go to eclipse. Before we create a new project for our application, we need to setup the server. Select File—>New—>Other. From the tree, Select Server.

Choose Apache—>Tomcat v7.0 Server and set the runtime environment.

Next, create a new project. Select File—>New—>Dynamic Web Project.

Enter “SimpleJspServletDB” as the project name. Select target runtime to Apache Tomcat v7.0 which we already setup before. Click Finish.

Copy the standard.jar, mysql-connector jar and jstl jar to WEB-INF—>lib folder.

Creating Package structure


Create four packages in the src folder.
  • org.avid.controller: contains the servlets
  • org.avid.dao: contains the logic for database operation
  • org.avid.model: contains the POJO (Plain Old Java Object). Each class in this package represents the database table. For this tutorial, however, we only have one table.
  • org.avid.util : contains the class for initiating database connection

Creating Model - POJOs


Next, create a new Java class. in org.avid.model folder. Name it “User.java” and insert these following codes. Each of the variables in this class represents the field in USERS table in our database.

package org.avid.model;

import java.util.Date;

public class User {

    private int userid;
    private String firstName;
    private String lastName;
    private Date dob;
    private String email;
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Date getDob() {
        return dob;
    }
    public void setDob(Date dob) {
        this.dob = dob;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User [userid=" + userid + ", firstName=" + firstName
                + ", lastName=" + lastName + ", dob=" + dob + ", email="
                + email + "]";
    }  
}

Creating DB Connection Utility


Create a new class in org.avid.util package and name it DbUtil.java. This class handles the database connection to our MySQL server. In this class, we read a .properties file which contains the information necessary for the connection.

package org.avid.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class DbUtil {

    private static Connection connection = null;

    public static Connection getConnection() {
        if (connection != null)
            return connection;
        else {
            try {
                Properties prop = new Properties();
                InputStream inputStream = DbUtil.class.getClassLoader().getResourceAsStream("/db.properties");
                prop.load(inputStream);
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String user = prop.getProperty("user");
                String password = prop.getProperty("password");
                Class.forName(driver);
                connection = DriverManager.getConnection(url, user, password);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return connection;
        }

    }
}

Create the properties file directly under the src folder. Create a new file, name it db.properties. Put the following information inside.

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
user=admin
password=test

Creating Data Access Object (DAO)


Next, create a new class in org.avid.dao package, name it UserDao.java. Dao stands for Data Access Object. It contains the logic for  database operation.

package org.avid.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.avid.model.User;
import org.avid.util.DbUtil;

public class UserDao {

    private Connection connection;

    public UserDao() {
        connection = DbUtil.getConnection();
    }

    public void addUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("insert into users(firstname,lastname,dob,email) values (?, ?, ?, ? )");
            // Parameters start with 1
            preparedStatement.setString(1, user.getFirstName());
            preparedStatement.setString(2, user.getLastName());
            preparedStatement.setDate(3, new java.sql.Date(user.getDob().getTime()));
            preparedStatement.setString(4, user.getEmail());
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void deleteUser(int userId) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("delete from users where userid=?");
            // Parameters start with 1
            preparedStatement.setInt(1, userId);
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void updateUser(User user) {
        try {
            PreparedStatement preparedStatement = connection
                    .prepareStatement("update users set firstname=?, lastname=?, dob=?, email=?" +
                            "where userid=?");
            // Parameters start with 1
            preparedStatement.setString(1, user.getFirstName());
            preparedStatement.setString(2, user.getLastName());
            preparedStatement.setDate(3, new java.sql.Date(user.getDob().getTime()));
            preparedStatement.setString(4, user.getEmail());
            preparedStatement.setInt(5, user.getUserid());
            preparedStatement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    public List<User> getAllUsers() {
        List<User> users = new ArrayList<User>();
        try {
            Statement statement = connection.createStatement();
            ResultSet rs = statement.executeQuery("select * from users");
            while (rs.next()) {
                User user = new User();
                user.setUserid(rs.getInt("userid"));
                user.setFirstName(rs.getString("firstname"));
                user.setLastName(rs.getString("lastname"));
                user.setDob(rs.getDate("dob"));
                user.setEmail(rs.getString("email"));
                users.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return users;
    }

    public User getUserById(int userId) {
        User user = new User();
        try {
            PreparedStatement preparedStatement = connection.
                    prepareStatement("select * from users where userid=?");
            preparedStatement.setInt(1, userId);
            ResultSet rs = preparedStatement.executeQuery();

            if (rs.next()) {
                user.setUserid(rs.getInt("userid"));
                user.setFirstName(rs.getString("firstname"));
                user.setLastName(rs.getString("lastname"));
                user.setDob(rs.getDate("dob"));
                user.setEmail(rs.getString("email"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return user;
    }
}


Creating Contrrollers


Finally, create a new Servlet inside the org.avid.controller package and name it UserController.java

package org.avid.controller;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.avid.dao.UserDao;
import org.avid.model.User;

public class UserController extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static String INSERT_OR_EDIT = "/user.jsp";
    private static String LIST_USER = "/listUser.jsp";
    private UserDao dao;

    public UserController() {
        super();
        dao = new UserDao();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String forward="";
        String action = request.getParameter("action");

        if (action.equalsIgnoreCase("delete")){
            int userId = Integer.parseInt(request.getParameter("userId"));
            dao.deleteUser(userId);
            forward = LIST_USER;
            request.setAttribute("users", dao.getAllUsers());  
        } else if (action.equalsIgnoreCase("edit")){
            forward = INSERT_OR_EDIT;
            int userId = Integer.parseInt(request.getParameter("userId"));
            User user = dao.getUserById(userId);
            request.setAttribute("user", user);
        } else if (action.equalsIgnoreCase("listUser")){
            forward = LIST_USER;
            request.setAttribute("users", dao.getAllUsers());
        } else {
            forward = INSERT_OR_EDIT;
        }

        RequestDispatcher view = request.getRequestDispatcher(forward);
        view.forward(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User user = new User();
        user.setFirstName(request.getParameter("firstName"));
        user.setLastName(request.getParameter("lastName"));
        try {
            Date dob = new SimpleDateFormat("MM/dd/yyyy").parse(request.getParameter("dob"));
            user.setDob(dob);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        user.setEmail(request.getParameter("email"));
        String userid = request.getParameter("userid");
        if(userid == null || userid.isEmpty())
        {
            dao.addUser(user);
        }
        else
        {
            user.setUserid(Integer.parseInt(userid));
            dao.updateUser(user);
        }
        RequestDispatcher view = request.getRequestDispatcher(LIST_USER);
        request.setAttribute("users", dao.getAllUsers());
        view.forward(request, response);
    }
}

Creating View


Now, it’s time for us to create the jsp, the view for our application. Under the WebContent folder, create a jsp file, name it index.jsp


<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<jsp:forward page="/UserController?action=listUser" />
</body>
</html>

This jsp serves as the entry point for our application. In this case, it will redirect the request to our servlet to list all the users in the database.

Next, create the jsp to list all the users in the WebContent folder. Name it listUser.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Show All Users</title>
</head>
<body>
    <table border=1>
        <thead>
            <tr>
                <th>User Id</th>
                <th>First Name</th>
                <th>Last Name</th>
                <th>DOB</th>
                <th>Email</th>
                <th colspan=2>Action</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="${users}" var="user">
                <tr>
                    <td><c:out value="${user.userid}" /></td>
                    <td><c:out value="${user.firstName}" /></td>
                    <td><c:out value="${user.lastName}" /></td>
                    <td><fmt:formatDate pattern="yyyy-MMM-dd" value="${user.dob}" /></td>
                    <td><c:out value="${user.email}" /></td>
                    <td><a href="UserController?action=edit&userId=<c:out value="${user.userid}"/>">Update</a></td>
                    <td><a href="UserController?action=delete&userId=<c:out value="${user.userid}"/>">Delete</a></td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
    <p><a href="UserController?action=insert">Add User</a></p>
</body>
</html>

In this jsp, we use JSTL to connect between the jsp and the servlet. We should refrain from using scriplet inside the jsp because it will make the jsp more difficult to maintain. Not to mention it will make the jsp looks ugly.

Next, create a new jsp in WebContent folder and name it user.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<link type="text/css"
    href="css/ui-lightness/jquery-ui-1.8.18.custom.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.18.custom.min.js"></script>
<title>Add new user</title>
</head>
<body>
    <script>
        $(function() {
            $('input[name=dob]').datepicker();
        });
    </script>

    <form method="POST" action='UserController' name="frmAddUser">
        User ID : <input type="text" readonly="readonly" name="userid"
            value="<c:out value="${user.userid}" />" /> <br />
        First Name : <input
            type="text" name="firstName"
            value="<c:out value="${user.firstName}" />" /> <br />
        Last Name : <input
            type="text" name="lastName"
            value="<c:out value="${user.lastName}" />" /> <br />
        DOB : <input
            type="text" name="dob"
            value="<fmt:formatDate pattern="MM/dd/yyyy" value="${user.dob}" />" /> <br />
        Email : <input type="text" name="email"
            value="<c:out value="${user.email}" />" /> <br /> <input
            type="submit" value="Submit" />
    </form>
</body>
</html>


Deployment Descriptor



Lastly, check the web.xml file located in WebContent—>WEB-INF folder in your project structure. Make sure it looks like this

<?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">
  <display-name>SimpleJspServletDB</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>UserController</display-name>
    <servlet-name>UserController</servlet-name>
    <servlet-class>org.avid.controller.UserController</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UserController</servlet-name>
    <url-pattern>/UserController</url-pattern>
  </servlet-mapping>
</web-app>

That is it. Right click the project name and run it using Run As–>Run on server option.

Jul 22, 2009

Using hibernate and struts together

    This article is to use hibernate with struts. As when we use hibernate, we have to set values of all fields externally. If we use struts with hibernate then all the values are set by struts. So it helps decreasing the number of lines of code. As well struts also helps in organizing the application

(1)    Configure the struts configuration in web.xml. If you don't know how to do so then first read a little about struts. At: Struts Action Example

(2)    In struts-config.xml define the action and form.
        e.g.
        <!-- ========== Form Bean Definitions ================= -->
        <form-beans>
            <form-bean name="User" type="com.persistence.UserVO"/>
        </form-beans>

        <!-- ========== Action Mapping Definitions ============ -->
    <action-mappings>
            <action path="/user" type="com.control.UserController" name="User" input="/home.jsp">
                <forward name="success" path="/home.jsp"/>
                <forward name="failure" path="/room.jsp"/>
            </action>

        </action-mappings>

(3)    Now create bean class as per the requirement the database as well HTML form. E.g.
        import org.apache.struts.action.ActionForm;

        public class UserVO extends ActionForm {
            private int id;
            private String userName;
            private String userPassword;
            private String userFirstName;
            private String userLastName;
            private String userEmail;

            // ----- getter and setter methods for all fields
        }

        But keep one thing clear that the fields of bean class must have same name as the fields of HTML form you submit from. Here I created this class as my HTML form is as like below.

        <form action="user.do" method="post"><br />
            Name:<input type="text" name="username" /> <br />
            Password:<input type="password" name="userPassword" /> <br />
            First name:<input type="text" name="userFirstName" /> <br />
            Last name:<input type="text" name="userLastName" /> <br />
            E-mail:<input type="text" name="userEmail" />
            <input type="submit">
        </form>

(4)    Now configure hibernate configuration files. First of all create hibernate.cfg.xml file as per your requirements. If you don't know how to create then please read about hibernate first. Hibernate tutorial

        Then after create *.hbn.xml file to map bean class with database table (here * in the name means you can give name as per your choice). As below

        <hibernate-mapping>
            <class name="com.persistence.UserVO" table="contact">
                <id column="USER_ID" name="id" type="int">
                    <generator class="native" />
                </id>
            <property column="USER_NAME" name="userName" type="java.lang.String" />
            <property column="USER_PASSWORD" name="userPassword" type="java.lang.String" />
            <property column="USER_FIRST_NAME" name="userFirstName" type="java.lang.String" />
            <property column="USER_LAST_NAME" name="userLastName" type="java.lang.String" />
            <property column="USER_EMAIL" name="userEmail" type="java.lang.String" />
        </class>
        </hibernate-mapping>

        PLEASE NOTE:
            This is main part where you have to take enough care. In class tag value of attribute name must be equal to the value of attribute type in tag form-bean.
            As well in id and property tags column name must contain the name of column of your table and name tag must contain the value you define in bean class.

(5)    Now define the class extending Action class of struts' action class as below.

        public class UserController extends Action {
            public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){
                try {
                    UserVO user = (UserVO)form;

                    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
                    Session session = sessionFactory.getCurrentSession();
                    Transaction t = session.beginTransaction();
                    session.saveOrUpdate(user);
                    t.commit();

                    return mapping.findForward("success");

                } catch (Exception e) {
                    return mapping.findForward("failure");
                }
            }
        }

May 25, 2009

Struts – Action – Example

    In my earlier post (Struts - What & Why?) I have explained the basic architecture of struts base application. Now I gonna explain you how to create application through struts.

    There is a predefined structure to implement struts in our web application.

(1)    First of all create web.xml. Declare a servlet as below.
e.g.
<servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
        <param-name>application</param-name>
        <param-value>ApplicationResources</param-value>
    </init-param>
    <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

    We are not declaring any controller servlet here. As we are going to use struts. In struts controller servlet are being declared in struts-comfig.xml.

(2)    Create one file struts-config.xml. place this file in WEB-INF directory.
e.g.
<struts-config>

    <!-- Form Bean Definitions -->
    <form-beans>
        <form-bean name="submitForm" type="com.forms.SubmitForm"/>
    </form-beans>

    <!-- Action Mapping Definitions -->
    <action-mappings>
        <action path="/submit" type="com.action.SubmitAction" name="submitForm">
            <forward name="success" path="/index.jsp"/>
            <forward name="failure" path="/submit.jsp"/>
        </action>

    </action-mappings>
        <message-resources parameter="ApplicationResources"/>
    </struts-config>

    Here we declared one action named submitForm. SubmitForm defines path /submit so whenever server request for /submit.do submitForm action will be called.

    forward tag defines that where to forward request after its processing. Here we define submit.jsp for failure. So if request been failed to process then server will forward the request to submit.jsp. As well for success we define index.jsp.

(3)    Now define a class SubmitAction extending org.apache.struts.action.Action class.
As in servlet, we defines a method as doPost or doGet to process. Here define a method execute as in example.
e.g.
public class SubmitAction extends Action {
    public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){

        /* here we gets object of ActionMapping, ActionForm, HttpServletRequest and HttpResponse.*/

        SubmitForm submitForm = (SubmitForm)form;

        /* if lastName field left blank then procees will be stoped and control will go to submit form again */
        if(submitForm.getLastName()==null)
            return mapping.findForward("failure");

        String lastName = submitForm.getLastName();
        request.setAttribute("lastName", lastName.toUpperCase());

        return mapping.findForward("success");
    }
}

mapping : this object is used to forward request after processing as in example.
form : explain later in this post.

(4)    Now just look at the struts-config.xml, there is tag defined by form-beans. This tag defines the form class. The form class is a simple javabean which contains the fields, we are going to pass through the form from jsp or html. Fields' name must match with the names of the parameter of the request.
e.g.
public class SubmitForm extends ActionForm {
    private String lastName = "";
    private String address = "";

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

    Here parameter passed through the /submit.do request must be lastName and address.

    Whenever one submit the form from submit.jsp all the fields of form class will be set with the values passed in the request. So the object we are getting in action class as argument have all the field filled by the user.

(5)    Now for the testing create one jsp named submit.jsp.
e.g.
<form action="/submit" method="post">
    Last name: <input type="text" name="lastName">
    address:<br/><textarea name="address" rows="2" cols="30"> address</textarea>
</form>

    This is how the whole structure of a struts action implemented. This is a very basic functionality. This may be extend to a large application where more one controller are defined as well as forms.

Mar 2, 2009

Prevent Duplicate Form Submission

Duplicate form submissions can occur in many ways :
  • Using Refresh button
  • Using the browser back button to traverse back and resubmit form
  • Using Browser history feature and re-submit form.
  • Malicious submissions to adversely impact the server or personal gains
  • Clicking more than once on a transaction that take longer than usual
Effect :

Think about a online shopping site, You are buying from a online shopping store. You hava submitted the form by clicking submit button screen comes with "Please wait...." and stays for a long you worried and press submit again what happens the first click submitted first shopping and second click requests for the same order again. And you have to pay for same item twice.

This is only the one case you may be pay twice, there are many others factors which can affects.

Solution :
  1. Disable submit button on first time it is clicked.
    This helps prevent duplicate form submission from user aggresion impatient. But not from the others mentioned above.
    E.g. <input type="submit" name="submit" onclick="this.disabled='true';/*your other function calling*/">

  2. Using Struts :
    1. By forwarding twice :

      The easy solution to this problem is to use HTTP redirect after the form submission. Suppose that the CustomerForm submission results in showing a page called Success.jsp. When HTTP redirect is used, the URL in the URL bar becomes /App1/Success.jsp instead of /App1/submitCustomerForm.do. When the page refreshed, it is the Success.jsp that is loaded again instead of App1/submitCustomerForm.do. Hence the form is not submitted again. To use the HTTP redirect feature, the forward is set as follows:

      <forward name=”success” path=”/Success.jsp” redirect=”true” />

      However there is one catch. With the above setting, the actual JSP name is shown in the URL. Whenever the JSP name appears in the URL bar, it is a candidate for ForwardAction. Hence change the above forward to be as follows:

      <forward name=”success” path=”/GotoSuccess.do” redirect=”true” />

      Where GotoSuccess.do is another action mapping using ForwardAction as follows:

      <action path=”/GotoSuccess” type=”org.apache.struts.actions.ForwardAction” parameter=”/Success.jsp” validate=”false” />

      Now, you have now addressed the duplicate submission due to accidental refreshing by the customer Problem : It does not prevent you from intentionally going back in the browser history and submitting the form again. Malicious users might attempt this if the form submissions benefit them or adversely impact the server.

    2. Synchronizer Token :

      Struts provide a token system which help solving this problem. Steps of implementation :

      1. add follwing line in the first(the page containing form you like to prevent from duplication) page or servlet,

      2. <% String token = TokenProcessor.getInstance().generateToken(request); session.setAttribute("org.apache.struts.action.TOKEN"
        , token); %>
      3. make a hidden field in the form as follow,

      4. <input type="hidden"
        name="<%=.TOKEN_KEY%>"
        value="<%=token%>"/>

      5. Now in the Action class you created, change code as follow,

      6. .... if(isTokenValid(request)){
        // your code if form submitted first time
        } else {
        // your code if form is duplicate.
        }
        saveToken(request);
        .....

Jun 12, 2008

Controlling J2EE Module Depedencies

J2EE Module Dependencies is a critical issue in an enterprise application. You need your one web module to access some resources while prohibiting others. Similar is the case with EJB modules.

Let’s figure it out with Eclipse Web Tools Platform. I consider that you all have ability to create projects and modules in Eclipse; so skipping those steps. I have Eclipse 3.3 with WTP 2.0 M6.

I have created project with following details.

MyProject – Enterprise project

MyEJB_Module – Contains bean class

MyEJBClient_Module – Contains interfaces of EJB, VO, and BeanUtil.

MyWeb_Modules – Holds JSPs, servlets and all presentation tier stuffs.

MyJava_Module – Contains common classes like constants, utilities.

Starting with MyProject, select properties from right click menu. In property dialog, select “J2EE Module Dependencies”. You will find all the modules. Select all as project is dependent on all modules.

Now you can configure dependency of individual module, let’s take an example of web module. In “J2EE Module Dependencies” window, you will find a radio button group which would has by default “Use EJB Client Jars” option selected. That radio button groups defines visibility of EJB jar.

As clients of any EJB should be isolated from bean classes, it is preferable not to select other options where you can define dependencies with EJB jar file. After all, EJB clients should not have any kind of dependencies with EJB jar.

Now here if I select MyEJB_ModuleClient.jar only, MyWeb_Module won’t able to access classes defined in MyJava_Module until you redefine module dependencies.

Similarity you can define dependencies with Utility project, specifically saying third party libraries. You want one module to access one jar and isolate others all you need to do is add library in main project (MyProject in my case) and then configure dependencies of other modules.

This feature takes care of dependencies on behalf of you and let you concentrate on other tasks.