How do I create a hit counter servlet?

Here we have a simple example of creating a hit counter using servlet. The servlet updates the hits counter every time a page is visited and display the number of hits as an image. The image is generated at runtime using Java’s java.awt.Graphic2D and javax.imageio.ImageIO class.

To store the number of visit data we create a table hit_counter with a single field called counter and set the initial value of the counter to zero. Below is the HitCounterServlet servlet code.

package org.kodejava.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.*;

@WebServlet(name = "HitCounterServlet", urlPatterns = "/hitcounter")
public class HitCounterServlet extends HttpServlet {
    private static final String URL = "jdbc:mysql://localhost/kodejava";
    private static final String USERNAME = "kodejava";
    private static final String PASSWORD = "s3cr*t";

    @Override
    public void init() throws ServletException {
        super.init();
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        updateHitCounter();
        getHitCounterImage(response);
    }

    private void updateHitCounter() {
        try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            // Update the hits counter table by incrementing the
            // counter every time a user hits our page.
            String sql = "UPDATE hit_counter SET counter = counter + 1";
            PreparedStatement stmt = connection.prepareStatement(sql);
            stmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private void getHitCounterImage(HttpServletResponse response) throws IOException {
        String hits = "";
        try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            // Get the current hits counter from database.
            String sql = "SELECT counter FROM hit_counter";
            PreparedStatement stmt = connection.prepareStatement(sql);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                hits = rs.getString("counter");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // Create an image of our counter to be sent to the browser.
        BufferedImage buffer = new BufferedImage(100, 20, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffer.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setFont(new Font("Roboto", Font.BOLD, 20));
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 100, 30);
        g.setColor(Color.BLACK);
        g.drawString(hits, 0, 20);

        response.setContentType("image/png");
        OutputStream os = response.getOutputStream();
        ImageIO.write(buffer, "png", os);
        os.close();
    }
}

To display the hits counter image on the JSP page, create an img tag with the source (src) point to our HitCounterServlet servlet url.

Visited for: <img src="http://localhost:8080/hitcounter" alt="Hit Counter"/> times.

Maven dependencies

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.1.0</version>
    </dependency>
</dependencies>

Maven Central Maven Central

Wayan

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.