How do I send a response status in Servlet?

package org.kodejava.servlet;

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.io.IOException;

@WebServlet(name = "ResponseStatusServlet", urlPatterns = "/response-status")
public class ResponseStatus extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // All response status is defined in the HttpServletResponse class. We
        // can then use these constants value to return process status to the
        // browser.
        response.setContentType("text/html");

        // Let say this servlet only handle request for page name inputForm. So
        // when user request for other page name error page not found 404 will
        // be returned, otherwise it will be 200 which mean OK.
        String page = request.getParameter("page");
        if (page != null && page.equals("inputForm")) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            final String message = "The requested page [" + page + "] not found.";
            response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
        }
    }
}

Here is a list of all available status code that are defined in the HttpServletResponse class.

STATUS CODE DESCRIPTION
SC_ACCEPTED Status code (202) indicating that a request was accepted for processing, but was not completed
SC_BAD_GATEWAY Status code (502) indicating that the HTTP server received an invalid response from a server it consulted when acting as a proxy or gateway
SC_BAD_REQUEST Status code (400) indicating the request sent by the client was syntactically incorrect
SC_CONFLICT Status code (409) indicating that the request could not be completed due to a conflict with the current state of the resource
SC_CONTINUE Status code (100) indicating the client can continue
SC_CREATED Status code (201) indicating the request succeeded and created a new resource on the server
SC_EXPECTATION_FAILED Status code (417) indicating that the server could not meet the expectation given in the Expect request header
SC_FORBIDDEN Status code (403) indicating the server understood the request but refused to fulfill it
SC_FOUND Status code (302) indicating that the resource reside temporarily under a different URI
SC_GATEWAY_TIMEOUT Status code (504) indicating that the server did not receive a timely response from the upstream server while acting as a gateway or proxy
SC_GONE Status code (410) indicating that the resource is no longer available at the server and no forwarding address is known
SC_HTTP_VERSION_NOT_SUPPORTED Status code (505) indicating that the server does not support or refuses to support the HTTP protocol version that was used in the request message
SC_INTERNAL_SERVER_ERROR Status code (500) indicating an error inside the HTTP server which prevented it from fulfilling the request
SC_LENGTH_REQUIRED Status code (411) indicating that the request cannot be handled without a defined Content-Length
SC_METHOD_NOT_ALLOWED Status code (405) indicating that the method specified in the Request-Line is not allowed for the resource identified by the Request-URI
SC_MOVED_PERMANENTLY Status code (301) indicating that the resource has permanently moved to a new location, and that future references should use a new URI with their requests
SC_MOVED_TEMPORARILY Status code (302) indicating that the resource has temporarily moved to another location, but that future references should still use the original URI to access the resource
SC_MULTIPLE_CHOICES Status code (300) indicating that the requested resource corresponds to any one of a set of representations, each with its own specific location
SC_NO_CONTENT Status code (204) indicating that the request succeeded but that there was no new information to return
SC_NON_AUTHORITATIVE_INFORMATION Status code (203) indicating that the meta information presented by the client did not originate from the server
SC_NOT_ACCEPTABLE Status code (406) indicating that the resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request
SC_NOT_FOUND Status code (404) indicating that the requested resource is not available
SC_NOT_IMPLEMENTED Status code (501) indicating the HTTP server does not support the functionality needed to fulfill the request
SC_NOT_MODIFIED Status code (304) indicating that a conditional GET operation found that the resource was available and not modified
SC_OK Status code (200) indicating the request succeeded normally
SC_PARTIAL_CONTENT Status code (206) indicating that the server has fulfilled the partial GET request for the resource
SC_PAYMENT_REQUIRED Status code (402) reserved for future use
SC_PRECONDITION_FAILED Status code (412) indicating that the precondition given in one or more of the request-header fields evaluated to false when it was tested on the server
SC_PROXY_AUTHENTICATION_REQUIRED Status code (407) indicating that the client MUST first authenticate itself with the proxy
SC_REQUEST_ENTITY_TOO_LARGE Status code (413) indicating that the server is refusing to process the request because the request entity is larger than the server is willing or able to process
SC_REQUEST_TIMEOUT Status code (408) indicating that the client did not produce a request within the time that the server was prepared to wait
SC_REQUEST_URI_TOO_LONG Status code (414) indicating that the server is refusing to service the request because the Request-URI is longer than the server is willing to interpret
SC_REQUESTED_RANGE_NOT_SATISFIABLE Status code (416) indicating that the server cannot serve the requested byte range
SC_RESET_CONTENT Status code (205) indicating that the agent SHOULD reset the document view which caused the request to be sent
SC_SEE_OTHER Status code (303) indicating that the response to the request can be found under a different URI
SC_SERVICE_UNAVAILABLE Status code (503) indicating that the HTTP server is temporarily overloaded, and unable to handle the request
SC_SWITCHING_PROTOCOLS Status code (101) indicating the server is switching protocols according to Upgrade header
SC_TEMPORARY_REDIRECT Status code (307) indicating that the requested resource resides temporarily under a different URI
SC_UNAUTHORIZED Status code (401) indicating that the request requires HTTP authentication
SC_UNSUPPORTED_MEDIA_TYPE Status code (415) indicating that the server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method
SC_USE_PROXY Status code (305) indicating that the requested resource MUST be accessed through the proxy given by the Location field

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I read servlet init parameter?

When creating a servlet we can use the @WebInitParam to define some init parameters in the servlet configuration section (@WebServlet). This init parameter can be used to define where a configuration file of our application is stored, define upload path, etc. This simple servlet below shows how to obtain these init parameters value.

package org.kodejava.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(
    name = "InitParameterServlet",
    urlPatterns = "/init-param",
    initParams = {
        @WebInitParam(name = "configPath", value = "F:/app/config"),
        @WebInitParam(name = "uploadPath", value = "F:/app/uploads")
    }
)
public class InitParameterServlet extends HttpServlet
        implements javax.servlet.Servlet {

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Get application configuration path
        String configPath = getInitParameter("configPath");
        String uploadPath = getInitParameter("uploadPath");

        System.out.println("configPath = " + configPath);
        System.out.println("uploadPath = " + uploadPath);
    }
}

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I read cookie in Servlet?

package org.kodejava.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "ReadCookieServlet", urlPatterns = "/read-cookie")
public class ReadCookieExample extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws IOException {
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();

        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            writer.println("Name: " + cookie.getName() + "; Value: " + cookie.getValue());
        }
    }
}

An example result of the servlet above is:

Name: username; Value: jduke 
Name: JSESSIONID; Value: AE819A3F74E3700838ADFC99485216DF

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I retrieve auto-generated keys?

package org.kodejava.jdbc;

import java.sql.*;

public class GetGeneratedKeyExample {
    private static final String URL = "jdbc:mysql://localhost/kodejava";
    private static final String USERNAME = "kodejava";
    private static final String PASSWORD = "s3cr*t";

    public static void main(String[] args) {
        try (Connection connection =
                     DriverManager.getConnection(URL, USERNAME, PASSWORD)) {

            // The orders table have an ID column which value will be auto
            // generated by database. When inserting a new record a new id
            // for the primary key will be generated, and we will get the
            // generated key, so we can use it in another process. For
            // instance if we have a master detail tables where the details
            // table required an id from the master table.
            String sql = """
                    INSERT INTO purchase_order (username, order_date)
                    VALUES ('foobar', '2021-09-25')
                    """;

            Statement stmt = connection.createStatement();

            // When executing the statement we can pass the
            // Statement.RETURN_GENERATED_KEYS so that we can later extract
            // the generated key from the statement object after executing
            // the query.
            stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);

            ResultSet keys = stmt.getGeneratedKeys();
            long lastKey = 1L;
            while (keys.next()) {
                lastKey = keys.getLong(1);
            }

            System.out.println("Last Key: " + lastKey);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

The structure of purchase_order table.

CREATE TABLE `purchase_order`
(
    `id`         bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `username`   varchar(50)         NOT NULL,
    `order_date` date                NOT NULL,
    PRIMARY KEY (`id`)
);

Maven Dependencies

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.4.0</version>
</dependency>

Maven Central

How do to commit or rollback transaction in JDBC?

Executing a database manipulation command such as insert, update or delete can sometime throw exception due to invalid data. To protect the integrity of our application data we must make sure that when a transaction fails we must rollback all the executed queries.

In this example we are using MySQL database. To enable transaction capability in MySQL make sure that you are using InnoDB storage engine to create your databases and tables.

package org.kodejava.jdbc;

import java.math.BigDecimal;
import java.sql.*;

public class TransactionRollbackExample {
    private static final String URL = "jdbc:mysql://localhost/kodejava";
    private static final String USERNAME = "kodejava";
    private static final String PASSWORD = "s3cr*t";

    public static void main(String[] args) {
        try (Connection conn =
                     DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            conn.setAutoCommit(false);

            String orderQuery = """
                    INSERT INTO purchase_order (username, order_date)
                    VALUES (?, ?)
                    """;

            try (PreparedStatement stmt = conn.prepareStatement(orderQuery,
                    PreparedStatement.RETURN_GENERATED_KEYS)) {
                stmt.setString(1, "jduke");
                stmt.setDate(2, new Date(System.currentTimeMillis()));
                stmt.execute();

                ResultSet keys = stmt.getGeneratedKeys();
                long orderId = 1L;
                if (keys.next()) {
                    orderId = keys.getLong(1);
                }

                // This is an invalid statement that will cause exception to
                // demonstrate a rollback.
                String orderDetailQuery = """
                        INSERT INTO purchase_order_detail (order_id, product_id, quantity, price)
                        VALUES (?, ?, ?, ?)
                        """;

                PreparedStatement detailStmt = conn.prepareStatement(orderDetailQuery);
                detailStmt.setLong(1, orderId);
                detailStmt.setInt(2, 1);
                detailStmt.setInt(3, 10);
                detailStmt.setBigDecimal(4, new BigDecimal("29.99"));
                detailStmt.execute();

                // Commit transaction to mark it as a success database operation
                conn.commit();
                System.out.println("Transaction commit...");
            } catch (SQLException e) {
                // Rollback any database transaction due to exception occurred
                conn.rollback();
                System.out.println("Transaction rollback...");
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Maven Dependencies

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.4.0</version>
</dependency>

Maven Central

How do I send a cookie in Servlet?

A cookie is a piece of information sent to a browser by a Web Server. The browser then returns that information to the Web server. This is how some Web pages remember your previous visits; for example, an e-commerce website might use a cookie to remember which items you’ve placed in your online shopping cart. Cookies can also store user preference information, login data, etc.

Here is an example to send a cookie in the HTTP response object to the client browser.

package org.kodejava.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "CookieServlet", urlPatterns = "/test-cookie")
public class WriteCookieExample extends HttpServlet {

    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");

        // Send a cookie named username to the client. There are some others
        // properties that we can set before we send the cookie, such as comments,
        // domain name, max age, path, a secure flag, etc.
        Cookie cookie = new Cookie("username", "jduke");
        response.addCookie(cookie);
    }
}

Maven dependencies

<!--https://search.maven.org/remotecontent?filepath=javax/servlet/javax.servlet-api/4.0.1/javax.servlet-api-4.0.1.jar-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I create a connection to MS Access database?

The following example show you how to create a connection to Microsoft Access databases. To allow the database access to be authenticated, the security user account can be added from File -> Info -> Users and Permissions screen.

Just like accessing any other databases in the Java platform we need a JDBC driver. To access Microsoft Access databases we can use UCanAccess, an open-source pure Java JDBC driver for Microsoft Access databases, it allows us to manipulate data in various versions of MS Access databases.

Here what we do in the code snippet below:

  • Prepare USERNAME and PASSWORD that will be used for accessing the database.
  • Define the database JDBC URL which contains the path to MS Access file.
  • Get the connection in try-with-resource statement using the DriverManager.getConnection() method and passes URL, USERNAME, and PASSWORD as arguments.
  • The connection will automatically closed by the try-with-resource when finished.
package org.kodejava.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class MSAccessConnect {
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "admin";

    private static final String URL =
            "jdbc:ucanaccess://C:/Users/wayan/Temp/kodejava.mdb;";

    public static void main(String[] args) throws Exception {
        try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            // Do something with the connection here!
            System.out.println("connection = " + connection);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

The connection object printed from the code above:

connection = net.ucanaccess.jdbc.UcanaccessConnection@63376bed[C:\Users\wayan\Temp\kodejava.mdb]

Before JDK 8, the sun.jdbc.odbc.JdbcOdbcDriver driver can be used to connect to Microsoft Access databases. On the example below we can either connect through the DSN created previously on the Windows system, or we can create it in our program as the long URL below.

In Microsoft Access 2003, to allow the database access to be authenticated the security user account can be added from Tools -> Security -> User and Group Accounts menu.

package org.kodejava.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class MSAccessODBCBridge {
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "admin";
    private static final String DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver";

    // If you want to use you ODBC DSN
    //private static final String URL = "jdbc:odbc:TestDB";
    private static final String URL =
            "jdbc:odbc:Driver={MICROSOFT ACCESS DRIVER (*.mdb, *.accdb)};" +
            "DBQ=C:/Users/wayan/Temp/kodejava.mdb;";

    public static void main(String[] args) throws Exception {
        Class.forName(DRIVER);
        try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            // Do something with the connection here!
            System.out.println("connection = " + connection);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

The connection object printed from the code above:

connection = sun.jdbc.odbc.JdbcOdbcConnection@4ec4f498

Maven Dependencies

<dependency>
  <groupId>io.github.spannm</groupId>
  <artifactId>ucanaccess</artifactId>
  <version>5.1.1</version>
</dependency>

How do I calculate process elapsed time?

This example shows us how to use the System.nanoTime() method to get the amount of time a process take place. Please be aware that the nano time value is not related to the real world time value.

package org.kodejava.lang;

public class ElapsedTimeExample {
    public static void main(String[] args) {
        // Get the start time of the process
        long start = System.nanoTime();
        System.out.println("Start: " + start);

        // Just do some a bit long process calculating the total value
        // of even number from zero to 10000
        int totalEven = 0;
        for (int i = 0; i < 10000; i++) {
            if (i % 2 == 0) {
                totalEven = totalEven + i;
            }
        }

        // Get the end time of the process
        long end = System.nanoTime();
        System.out.println("End  : " + end);

        long elapsedTime = end - start;

        // Show how long it took to finish the process
        System.out.println("The process took approximately: "
            + elapsedTime + " nano seconds");
    }
}

And example of the result are:

Start: 35034476484699
End  : 35034477434200
The process took approximately: 949501 nano seconds

How do I create a Hello World Applet?

The code below demonstrate the very basic of Java applet. Applet is a small Java application that can be embedded on the web browser.

package org.kodejava.applet;

import java.applet.*;
import java.awt.*;

public class HelloWorldApplet extends Applet {
    public void init() {
    }

    public void start() {
    }

    public void stop() {
    }

    public void destroy() {
    }

    public void paint(Graphics g) {
        g.setColor(Color.GREEN);
        g.drawString("Hello World", 50, 100);
    }
}

To display the applet we need to create an HTML document. Here is a simple example of the document.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Hello World Applet</title>
</head>

<body>
<applet
        code="org.kodejava.applet.HelloWorldApplet"
        height="250"
        width="250">
</applet>
</body>
</html>

You can now load the applet in your browser or by using the appletviewer utility.

appletviewer.exe hello-world-applet.html
** Deprecated: The Applet API is deprecated since JDK 9, no replacement.