Image uploading and saving into MySQL and then display image

Let us look at how to upload an image into MySQL DB and then display the image using JSP, Servlet and MySQL database.

Java Servlet API doesn't provide any method to handle file upload. So, we have to depend on a library provided by third parties. In this post I am going to use Commons Fileupload library provided by Apache Foundation.


•    commons-io-2.0.jar ( http://commons.apache.org/io/download_io.cgi )
•    commons-fileupload-1.2.2.jar ( http://commons.apache.org/fileupload/download_fileupload.cgi )

Now let us starts with a JSP file which has the following fields First Name, Last Name and Portrait Photo.

Upload.jsp
<%--
 *
 * Author           : Sanjeev Kulkarni
 * Project          : WebLearning
 * Created On       : 03-Jul-2013 3:12:44 PM
 *
--%>


<%@ 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>File Upload to Database Demo</title>
</head>
<body>
    <center>
        <h1>File Upload to Database Demo</h1>
        <form action="displayServlet" method="get">
            <table>
                <tr>
                    <td>
                        <div style="background: none repeat scroll 0 0 ghostwhite; height: 150px; width: 150px;">
                            <img src="displayServlet?id=13" height="150px" width="150px" alt="ProfilePic">
                    </div>
                    </td>
                </tr>
            </table>
        </form>
        <form method="post" action="uploadServlet" enctype="multipart/form-data">
            <table border="0">
                <tr>
                    <td>First Name: </td>
                    <td><input type="text" name="firstName" size="50"/></td>
                </tr>
                <tr>
                    <td>Last Name: </td>
                    <td><input type="text" name="lastName" size="50"/></td>
                </tr>
                <tr>
                    <td>Portrait Photo: </td>
                    <td><input type="file" name="photo" size="50"/></td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="Save">
                    </td>
                </tr>
            </table>
        </form>
    </center>
</body>
</html>


Once you upload the image and click on Save button, request will be sent to FileUploadDBServlet which process the request and stores the image into MySQL db.

FileUploadDBServlet.java 
 
package com.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

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;

/**
 * Servlet implementation class FileUploadDBServlet
 */
@WebServlet("/FileUploadDBServlet")
@MultipartConfig(maxFileSize = 10177215) // upload file's size up to 16MB
public class FileUploadDBServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FileUploadDBServlet() {
        super();
    }

    private String dbURL = "jdbc:mysql://localhost:3306/web_learning";
    private String dbUser = "root";
    private String dbPass = "root";
     
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // gets values of text fields
        String firstName = request.getParameter("firstName");
        String lastName = request.getParameter("lastName");
         
        InputStream inputStream = null; // input stream of the upload file
         
        // obtains the upload file part in this multipart request
        Part filePart = request.getPart("photo");
        if (filePart != null) {
            // prints out some information for debugging
            System.out.println(filePart.getName());
            System.out.println(filePart.getSize());
            System.out.println(filePart.getContentType());
             
            // obtains input stream of the upload file
            inputStream = filePart.getInputStream();
        }
         
        Connection conn = null; // connection to the database
        String message = null;  // message will be sent back to client
         
        try {
            // connects to the database
            DriverManager.registerDriver(new com.mysql.jdbc.Driver());
            conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
 
            // constructs SQL statement
            String sql = "INSERT INTO contacts (first_name, last_name, photo) values (?, ?, ?)";
            PreparedStatement statement = conn.prepareStatement(sql);
            statement.setString(1, firstName);
            statement.setString(2, lastName);
             
            if (inputStream != null) {
                // fetches input stream of the upload file for the blob column
                statement.setBlob(3, inputStream);
            }
 
            // sends the statement to the database server
            int row = statement.executeUpdate();
            if (row > 0) {
                message = "File uploaded and saved into database";
            }
        } catch (SQLException ex) {
            message = "ERROR: " + ex.getMessage();
            ex.printStackTrace();
        } finally {
            if (conn != null) {
                // closes the database connection
                try {
                    conn.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            // sets the message in request scope
            request.setAttribute("Message", message);
             
            // forwards to the message page
            getServletContext().getRequestDispatcher("/Message.jsp").forward(request, response);
        }
    }
}


So we are done with uploading of the image. So simple isn’t it! Now you have the image stored into the database, next question is how to retrieve the image? We know little bit about the TNIYBLOB,BLOB,MEDIUMBLOB,LONGBLOB and the content of these types are stored in the db as a binary object.

•    TINYBLOB: maximum length of 255 bytes
•    BLOB: maximum length of 65,535 bytes
•    MEDIUMBLOB: maximum length of 16,777,215 bytes
•    LONGBLOB: maximum length of 4,294,967,295 bytes



Note that if you generate your table from the JPA annotations, you can "control" the type MySQL will use by specifying the length attribute of the Column, for example:


@Lob 
@Basic(fetch = FetchType.LAZY)
@Column(length=100000)
private byte[] picture;


Depending on the length, you'll get:
       0 < length <=      255  -->  `TINYBLOB`
     255 < length <=    65535  -->  `BLOB`
   65535 < length <= 16777215  -->  `MEDIUMBLOB`
16777215 < length <=    2³¹-1  -->  `LONGBLOB`


In Open JPA if we do not provide FetchType, I was getting some warnings whenever I was running the enhancer tool for enhancing the entities. Now don’t worry about the JPA concept, we will concentrate just on servlet, jdbc.



DisplayServlet.java
 
package com.servlet;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

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

/**
 * Servlet implementation class DisplayServlet
 */
@WebServlet("/DisplayServlet")
public class DisplayServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    public void init() throws ServletException {

    }

    /**
     * @see HttpServlet#HttpServlet()
     */
    public DisplayServlet() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String imageId = request.getParameter("id");
        System.out.println(imageId);
        InputStream sImage;

        // Check if ID is supplied to the request.
        if (imageId == null) {
            // Do your thing if the ID is not supplied to the request.
            // Throw an exception, or send 404, or show default/warning image, or just ignore it.
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        try{
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_learning", "root","root");
            stmt = conn.prepareStatement("select * from contacts where contact_id=" + imageId);
            rs = stmt.executeQuery();
            if(rs.next()){
                System.out.println("Inside RS");
                byte[] bytearray = new byte[1048576];
                int size=0;
                sImage = rs.getBinaryStream(4);
                response.reset();
                response.setContentType("image/jpeg");
                while((size = sImage.read(bytearray)) != -1 ){
                    response.getOutputStream().
                    write(bytearray,0,size);
                }
            }

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




For displaying image in any of your JSP page you need to pass the id like below:

<img src="displayServlet?id=1" height="150px" width="150px" alt="ProfilePic">

There is one more method for displaying the image from DB. You can refer to the following post for the same: http://balusc.blogspot.in/2007/04/imageservlet.html#ImageServletServingFromDatabase

Hope this post helps for your development activities. See you then,

Sanjeev Kulkarni