Thursday 14 March 2013

Upload a file/image in Folder using Servlet

This Post shows how to implement a Java web application that uploads files to server and save the files into folders and save it's path into database.

Steps you need to follow
1. Create a Mysql database table.
2. Create a upload form page.
3. Create a folder in your 'C' drive named images;
4. Create a File upload Servlet.

Query for create a database table :

create database UploadFile;
use UploadFile;
CREATE TABLE customerDetail(
'contact_id' int(11) not null auto_increment,
'first_name' varchar(50) not null,
'last_name' varchar(50) not null,
'file' varchar(200) not null,
primary key(contact_id)
);


'photo' is varchar type because I am storing path of the file in this field, if you want to insert whole file in mysql database then you need to set type of  'file' to 'blob'. In this example i am not using blob because it may be cause of image distortion or a little bit hard to implement, in blob field firstly we need to covert file into bytes and then store in mysql.

Coding for uploadform.jsp

<%@ 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>
      <title>Image Upload</title>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>
    <form action="FileUploadServlet" method="post" enctype="multipart/form-data">
    <table width="400px" align="center" border=0>
       <tr>
           <td align="center" colspan=2>
            Image Details</td>
       </tr>
       <tr>
           <td>First Name </td>
           <td>
               <input type="text" name="firstname">
           </td>
       </tr>
       <tr>
           <td>Last Name </td>
           <td>
               <input type="text" name="lastname">
           </td>
       </tr>
       <tr>
           <td>Image Link: </td>
           <td>
               <input type="file" name="file">
           </td>
       </tr>
       <tr>
           <td></td>
           <td>
              <input type="submit" name="submit" value="Submit"></td>
       </tr>
   </table>
</form>
</body>
</html>

You need to set enctype of form tag to "multipart/form-data" it tells that form contain multipart data.
This page contain two text fields for first name and last name and one file type field for files, after submitting the form data send to FileUploadServlet servlet where all other processing is to be done.

 Coding for FileUploadServlet.java:


import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;


@WebServlet("/FileUploadServlet")
@MultipartConfig(fileSizeThreshold=1024*1024*2, // 2MB
                 maxFileSize=1024*1024*10,      // 10MB
                 maxRequestSize=1024*1024*50)

public class FileUploadServlet extends HttpServlet {
    private static final String SAVE_DIR="images";
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, ClassNotFoundException, SQLException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
            String savePath = "C:" + File.separator + SAVE_DIR;
                File fileSaveDir=new File(savePath);
                if(!fileSaveDir.exists()){
                    fileSaveDir.mkdir();
                }
            String firstName=request.getParameter("firstname");
            String lastName=request.getParameter("lastname");
            Part part=request.getPart("file");
            String fileName=extractFileName(part);
            /*if you may have more than one files with same name then you can calculate some random characters and append that characters in fileName so that it will  make your each image name identical.*/
            part.write(savePath + File.separator + fileName);
           /* 
            //You need this loop if you submitted more than one file
            for (Part part : request.getParts()) {
            String fileName = extractFileName(part);
            part.write(savePath + File.separator + fileName);
        }*/
            Class.forName("com.mysql.jdbc.Driver");
            Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/UploadFile","root","root");
            String query="INSERT INTO customerDetail (first_name, last_name, file) values (?, ?, ?)";
           
                PreparedStatement pst;
                pst=con.prepareStatement(query);
                pst.setString(1, firstName);
                pst.setString(2,lastName);
                String filePath= savePath + File.separator + fileName ;
                pst.setString(3,filePath);
                pst.executeUpdate();
    }
    // file name of the upload file is included in content-disposition header like this:
    //form-data; name="dataFile"; filename="PHOTO.JPG"
    private String extractFileName(Part part) {
        String contentDisp = part.getHeader("content-disposition");
        String[] items = contentDisp.split(";");
        for (String s : items) {
            if (s.trim().startsWith("filename")) {
                return s.substring(s.indexOf("=") + 2, s.length()-1);
            }
        }
        return "";
    }
}


In this servlet, we use two annotations:
          @WebServlet: marks this servlet so that the servlet container will load it at startup, and map it   to the URL pattern /FileUploadServlet.
          @MultipartConfig: indicates this servlet will handle multipart request. We restrict maximum size of the upload file up to 16 MB.


Now your file is successfully uploaded in your folder and the path is stored in mysql.
Go in c drive and check it out and check for entry in mysql fire a query(select * from customerDetail) on mysql.

Thursday 21 February 2013

How ResultSet fetches data from database

ResultSet is set of rows from a database. When any statement object fires a query on database then output is stored in ResultSet object.
ResultSet access the results through a cursor and cursor moves row by row. It fetches one row at a time.
For Example:
We have a table named emp_info contains 4 column's 
"emp_id"  "emp_fname"  "emp_lname"  "emp_dob"
with 5 employees entries.

Code:
Connection conn=null;
Statement stmnt = null;
ResultSet rs = null;
try
{
   // Create the Statement
   stmnt = conn.createStatement();

   // Execute the query to obtain the ResultSet 
   rs = stmnt.executeQuery("select * from emp_info");
  
   // Fetches rows one by one
   // Loop executes five times because table contain record for five employees
   while(rs.next())
   {
      System.out.println("Emp ID: " + rs.getString("emp_id")); 
      System.out.println("First name: " + rs.getString("emp_fname"));
      System.out.println("Last name: " + rs.getString("emp_lname"));
      System.out.println("Date Of Birth: " + rs.getDate("emp_dob"));  
}
catch(Exception ex)
{
   System.err.println("Database exception: " + ex);
} 

rs.next() places the cursor on starting point of records and when next time it will execute, point the starting position of next record.
We can use columns number at the place of columns  name (rs.getString("emp_id"); => rs.getString(1);). Remember columns index started from 1.

Difference Between Prepared and PreparedStatement

Four Necessary steps to complete execution of a query:
                                1. Parse the incoming SQL Query
                                2. Compile the SQL Query
                                3. Plan/optimize the data acquisition path
                                4. Execute the optimized query / acquire and return data


A Statement will need to perform four steps above for each SQL query. A PreparedStatement pre-executes steps (1) - (3) in the execution process above. Thus, when creating a PreparedStatement some pre-optimization is performed immediately. The effect is to lessen the load on the database engine at execution time.

Another advantage of the PreparedStatement class is the ability to create an incomplete query and supply parameter values at execution time.
Query like this:-
"SELECT firstName FROM employees WHERE salary > ?");

after prepare a statement object we can set the values for incomplete places.
like this:-  stmnt.setInt(1, 200);

There are three different kinds of statements:
  • Statement: Used to implement simple SQL statements with no parameters.
  • PreparedStatement: Used for precompiling SQL statements that might contain input parameters.
  • CallableStatement: Used to execute stored procedures that may contain both input and output parameters.
 Statement Example:

Connection conn=null;
Statement stmnt = null;
ResultSet rs = null;
try
{
   // Create the Statement
   stmnt = conn.createStatement();

   // Execute the query to obtain the ResultSet 
   rs = stmnt.executeQuery("select * from aTable");
}
catch(Exception ex)
{

   System.err.println("Database exception: " + ex);
} 

PreparedStatement Example:

Connection conn=null;
PreparedStatement stmnt = null;
ResultSet rs = null;
try
{
   // Create the PreparedStatement 
   // Step 1-3 performed at here 
   stmnt = conn.prepareStatement("select * from aTable");

   // Execute the query to obtain the ResultSet 
   rs = stmnt.executeQuery();
}
catch(Exception ex)
{
   System.err.println("Database exception: " + ex);
} 


Parametrized PreparedStatement Example:

// Assume a database connection, conn.
PreparedStatement stmnt = null;
ResultSet rs = null;
try
{
  // Create the PreparedStatement, leaving a '?'
  // to indicate placement of a parameter.
  stmnt = conn.prepareStatement(
    "SELECT firstName FROM employees WHERE salary > ?");

  // Complete the statement 
  // Set 200 at the place of '?'
  stmnt.setInt(1, 200);

  // Execute the query to obtain the ResultSet 
  rs = stmnt.executeQuery();
}
  catch(Exception ex)
{
  System.err.println("Database exception: " + ex);
}