user1851487
user1851487

Reputation: 547

Image Servlet Image returning as null

Hi i have tried following this very helpful tut found here:

http://balusc.blogspot.co.uk/2007/04/imageservlet.html

I am following the tutorial to try and create my image servlet which retrieves an image from a database and displays it the the user on my jsp page. As far as i am aware the code looks ok, but the console is showing me a 500 internal error and my server console indicates that my Image variable is null here:

Image image = dataManager.getPhotos(homeId);

Below is my complete code:

@WebServlet(name = "ImageServlet", urlPatterns = {"/Image"})
public class ImageServlet extends HttpServlet {

private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
private static DatabaseConnector dataManager;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // Get ID from request.
    String homeId = request.getParameter("id");

    // Check if ID is supplied to the request.
    if (homeId == 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 {
        // Lookup Image by ImageId in database.
        // Do your "SELECT * FROM Image WHERE ImageID" thing.
        Image image = dataManager.getPhotos(homeId);

        // Check if image is actually retrieved from database.
        if (image == null) {
            // Do your thing if the image does not exist in database.
            // Throw an exception, or send 404, or show default/warning image, or just ignore it.
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        // Init servlet response.
        response.reset();
        response.setBufferSize(DEFAULT_BUFFER_SIZE);
        response.setContentType("image/png");
        response.setHeader("Content-Length", String.valueOf(image.getLength()));
        response.setHeader("Content-Disposition", "inline; filename=\"" + image.getHomeID() + "\"");

        // Prepare streams.
        BufferedInputStream input = null;
        BufferedOutputStream output = null;

        try {
            // Open streams.
            input = new BufferedInputStream(image.getContent(), DEFAULT_BUFFER_SIZE);
            output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

            // Write file contents to response.
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int length;
            while ((length = input.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
        } finally {
            // Gently close streams.
            close(output);
            close(input);
        }

    } catch (IllegalArgumentException ex) {
        Logger.getLogger(ImageServlet.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SQLException ex) {
        Logger.getLogger(ImageServlet.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(ImageServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private static void close(Closeable resource) {
    if (resource != null) {
        try {
            resource.close();
        } catch (IOException e) {
            // Do your thing with the exception. Print it, log it or mail it.
            e.printStackTrace();
        }
    }
}

My Database Connector below handles and retrieves the data below:

 public Image getPhotos(String homeID) throws
        IllegalArgumentException, SQLException, ClassNotFoundException {

    createConnection();

    Image img = new Image();

    ResultSet rs = null;
    PreparedStatement preparedStatement = null;

    String strQuery = "SELECT * "
            + "FROM home_photo "
            + "WHERE home_photo.home_id = ?";

    try {
        preparedStatement = conn.prepareStatement(strQuery);
        preparedStatement.setString(1, homeID);
        rs = preparedStatement.executeQuery();

        while (rs.next()) {
            img.setHomeID(rs.getInt("home_id"));
            img.setPhotoID(rs.getInt("photo_id"));
            img.setContent(rs.getBinaryStream("photo"));
            img.setDescription(rs.getString("description"));
            img.setLength(rs.getInt("length"));
            img.setContentType(rs.getString("type"));
        }

    } catch (SQLException e) {
        throw new SQLException(e);
    }

    closeConnection();
    return img;
}

Of which i cant see where it would return img and null?

Help appreciated.

Upvotes: 1

Views: 811

Answers (1)

BalusC
BalusC

Reputation: 1109635

The problem and the code suggests that it's actually the dataManager which is null. The code is written in such way that if the image would ever be null, then it would just return a 404, not a 500 with a NullPointerException.

You need to make sure that the dataManager is not null, e.g. by instantiating it in init() method, or if it's an EJB, by injecting it as @EJB.


Unrelated to the concrete problem, the DatabaseConnector being a static variable and the JDBC Connection being declared as an instance variable is also not a good sign. This code is not thread safe. Start here to learn how to write proper JDBC code: Is it safe to use a static java.sql.Connection instance in a multithreaded system? On the very same blog as you found the image servlet, you can also find a basic JDBC DAO tutorial.

Upvotes: 2

Related Questions