Java Backend Development Essentials

Core JDBC Concepts and Usage

JDBC Query Methods: executeQuery() vs. executeUpdate()

The method executeQuery() is used when you want to retrieve data from the database, typically using a SELECT statement. It returns a ResultSet object which contains the data returned by the query.

Example:

ResultSet rs = statement.executeQuery("SELECT * FROM users");
while (rs.next()) {
    System.out.println(rs.getString("username"));
}

The method executeUpdate() is used for SQL statements that change the data in the database, like INSERT, UPDATE, or DELETE. It returns an integer indicating the number of rows affected by the query.

Example:

int rowsAffected = statement.executeUpdate("UPDATE users SET status='active' WHERE id=1");
System.out.println(rowsAffected + " row(s) updated.");

JDBC Statement Interface Usage

The Statement interface in JDBC is used to execute SQL queries against a database. It is created by using a Connection object and is generally used for executing static SQL statements such as SELECT, INSERT, UPDATE, or DELETE.

Steps to use Statement:

  1. Load the JDBC driver.
  2. Establish a connection.
  3. Create a Statement object.
  4. Execute a query.
  5. Process the result (if any).
  6. Close the connection.

Example:

import java.sql.*;

public class StatementExample {
    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "password");
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM employees");

        while (rs.next()) {
            System.out.println(rs.getInt(1) + " " + rs.getString(2));
        }

        con.close();
    }
}

In this example, we use the Statement object to execute a SELECT query and print employee data.

JDBC Connection & Data Insertion Example

import java.sql.*;

public class InsertStudent {
    public static void main(String[] args) {
        try {
            // Load the JDBC driver
            Class.forName("com.mysql.cj.jdbc.Driver");

            // Establish the connection
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/college", "root", "password");

            // Create the SQL insert query
            String query = "INSERT INTO Student (id, name, age) VALUES (101, 'Alice', 20)";

            // Create Statement object
            Statement stmt = con.createStatement();

            // Execute the query
            int result = stmt.executeUpdate(query);
            System.out.println(result + " record inserted.");

            // Close the connection
            con.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

PreparedStatement & CallableStatement Usage

PreparedStatement

PreparedStatement is used to execute parameterized SQL queries. It is precompiled and prevents SQL injection attacks.

Example:

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/college", "root", "password");
PreparedStatement ps = con.prepareStatement("INSERT INTO Student (id, name, age) VALUES (?, ?, ?)");
ps.setInt(1, 102);
ps.setString(2, "Bob");
ps.setInt(3, 22);
ps.executeUpdate();

CallableStatement

CallableStatement is used to call stored procedures in the database.

Example:

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/college", "root", "password");
CallableStatement cs = con.prepareCall("{call add_student(?, ?, ?)}");
cs.setInt(1, 103);
cs.setString(2, "Charlie");
cs.setInt(3, 21);
cs.execute();

JDBC Driver Types Explained

There are four types of JDBC drivers:

  1. Type 1 – JDBC-ODBC Bridge Driver
    This driver uses ODBC to connect to the database. It acts as a bridge between JDBC and ODBC drivers. It is no longer recommended due to performance and platform dependency.

  2. Type 2 – Native-API Driver
    This driver uses native code libraries of the database. It is faster than Type 1 but platform-dependent and requires native binary code on the client system.

  3. Type 3 – Network Protocol Driver (Middleware Driver)
    It sends JDBC calls to a middleware server which translates them to database-specific calls. It is flexible and good for large-scale enterprise systems.

  4. Type 4 – Thin Driver (Pure Java Driver)
    It directly converts JDBC calls into database-specific calls using Java. It is platform-independent and the most commonly used driver in modern applications.

JDBC Architecture Fundamentals

JDBC (Java Database Connectivity) architecture is a multi-layered structure that allows Java applications to interact with databases in a standard way. The architecture has two main layers:

  1. JDBC API: This provides application-level access to relational databases. It allows Java programs to use SQL statements for querying and updating the database.

  2. JDBC Driver Manager: This manages different JDBC drivers and establishes a connection between the Java application and the database using an appropriate driver.

Steps in JDBC Architecture:

  • Load the driver using Class.forName().
  • Create a connection using DriverManager.getConnection().
  • Create a Statement object.
  • Execute the query.
  • Process the result.
  • Close the connection.

JDBC supports four types of drivers (Type 1 to Type 4) for flexibility and cross-database connectivity.

Java Servlet Essentials

Understanding Java Servlets

A Servlet is a Java program that runs on a web server and handles requests from web clients (usually browsers). It is used to generate dynamic web content and is part of Java’s server-side technology. Servlets respond to HTTP requests and can be used for tasks such as processing forms, managing sessions, or generating HTML pages dynamically.

ServletConfig vs. ServletContext Explained

ServletConfig

  • ServletConfig is used to pass initialization parameters to a specific servlet.
  • It is defined in the web.xml file and is unique to each servlet.
  • Useful for servlet-specific configuration like database URLs, file paths, etc.

Example (web.xml):

<servlet>
  <servlet-name>MyServlet</servlet-name>
  <servlet-class>MyServlet</servlet-class>
  <init-param>
    <param-name>dbURL</param-name>
    <param-value>jdbc:mysql://localhost/mydb</param-value>
  </init-param>
</servlet>

Example (Java):

public void init(ServletConfig config) throws ServletException {
    String dbURL = config.getInitParameter("dbURL");
    System.out.println("DB URL: " + dbURL);
}

ServletContext

  • ServletContext is shared by all servlets in a web application.
  • Used to get application-wide parameters and resources.
  • Can also be used to set and get attributes shared between servlets.

Example (web.xml):

<context-param>
  <param-name>appName</param-name>
  <param-value>StudentPortal</param-value>
</context-param>

Example (Java):

ServletContext context = getServletContext();
String name = context.getInitParameter("appName");
System.out.println("App Name: " + name);

In summary, ServletConfig provides configuration specific to a single servlet, while ServletContext provides information and shared resources for the entire web application.

HTTP GET vs. POST Methods

GET

  • Appends data in the URL.
  • Used for idempotent operations (like querying data).
  • Not secure for sensitive data.

Example (HTML):

<form method="get" action="GetServlet">
  <input type="text" name="username">
  <input type="submit">
</form>

Example (Java Servlet):

doGet(HttpServletRequest request, HttpServletResponse response) {
    String name = request.getParameter("username");
}

POST

  • Sends data in the request body.
  • Used for sensitive or large data like form submissions.
  • More secure than GET.

Example (HTML):

<form method="post" action="PostServlet">
  <input type="text" name="username">
  <input type="submit">
</form>

Example (Java Servlet):

doPost(HttpServletRequest request, HttpServletResponse response) {
    String name = request.getParameter("username");
}

In summary, GET is suitable for retrieving data and has limitations on data size and security, while POST is preferred for submitting data that modifies server state or contains sensitive information.

Servlet Lifecycle Stages Explained

The Servlet lifecycle consists of three main stages:

  1. Initialization (init() method)
    Called once when the servlet is first loaded into memory. Used for initialization tasks, such as establishing database connections or loading configuration files.

    public void init() throws ServletException {
        // Code here runs only once
    }
  2. Request Handling (service() method)
    Called each time the servlet receives a request. It dispatches the request to doGet() or doPost() depending on the HTTP method. This is the core method that handles client requests and generates responses.

    public void service(HttpServletRequest req, HttpServletResponse res) {
        // Handle client request
    }
  3. Destruction (destroy() method)
    Called once when the servlet is being unloaded from the container. Used to release resources, close database connections, or perform any necessary cleanup tasks.

    public void destroy() {
        // Cleanup code
    }

Understanding response.sendRedirect()

The response.sendRedirect() method is used in servlets to redirect the client to a different URL. It tells the browser to make a new request to the specified location. This is often used after form submissions, successful login, or logout to navigate users to another page.

Use Cases:

  • Redirecting to a login page after logout.
  • Moving to another domain or servlet.
  • Navigating to a success page after a form submission.

Example:

doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.sendRedirect("https://www.google.com");
}

This tells the client’s browser to navigate to Google after accessing the servlet. This redirection is done on the client side, which means the browser’s URL will also change. Unlike server-side forwarding, redirection does not share the request object between servlets or pages.

HTTP Session Management in Java

What is Session? Why we require Session?

A Session is a mechanism used to maintain state or data across multiple HTTP requests from the same client. Since HTTP is stateless, a session helps the server remember users across different pages or interactions. It is useful for storing information like user login status, shopping cart contents, and user preferences during a web application session.

Session Management Techniques in Web Applications

Sessions can be managed in multiple ways in a web application:

  1. HTTP Session (Using HttpSession Object)
    Java provides the HttpSession interface to store and retrieve session information. This is the most common and recommended way to manage sessions in Java web applications.

    Example:

    HttpSession session = request.getSession();
    session.setAttribute("username", "john123");
  2. Cookies
    Cookies are small text files stored on the client’s browser. They can store session data, typically a session ID that the server uses to retrieve session-specific information.

    Example:

    Cookie c = new Cookie("username", "john123");
    response.addCookie(c);
  3. URL Rewriting
    This involves appending session information in the URL as a query string. It is useful when cookies are disabled in the client’s browser, but it can make URLs look messy and is less secure.

    Example:

    response.sendRedirect("dashboard.jsp?username=john123");
  4. Hidden Form Fields
    Data can be stored in hidden fields within HTML forms to persist it across multiple requests. This method requires form submissions for data transfer and is not suitable for large amounts of data.

    Example (HTML):

    <input type="hidden" name="username" value="john123">

Each method has its own use case, depending on security, usability, and browser compatibility requirements.

Advanced Java Web Concepts

SOAP vs. RESTful Web Services

SOAP (Simple Object Access Protocol) and RESTful (Representational State Transfer) are two approaches for implementing web services. SOAP is a protocol based on XML that follows a strict messaging structure and relies heavily on standards such as WSDL (Web Services Description Language) and XML Schema. It supports complex operations like security, transactions, and ACID compliance. It uses only XML for message format and typically works over HTTP, SMTP, or other protocols. On the other hand, RESTful web services are based on standard HTTP methods like GET, POST, PUT, and DELETE. REST uses URIs to access resources and can support multiple data formats including JSON, XML, HTML, and plain text, making it lighter and faster compared to SOAP. REST is stateless and often preferred for its simplicity and performance in web and mobile applications.

URLConnection Class Demonstration

The URLConnection class is part of Java’s networking package used to read from and write to any URL. Below is a simple demonstration program that connects to a web page and prints its content:

import java.io.*;
import java.net.*;

public class URLConnectionDemo {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://www.example.com");
            URLConnection connection = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            String inputLine;
            while ((inputLine = in.readLine()) != null) {
              System.out.println(inputLine);
            }
            in.close();
        } catch (Exception e) {
            System.out.println("Error: " + e);
        }
    }
}

This code opens a connection to “example.com”, reads the HTML content line by line, and prints it to the console.

RMI Application Architecture

Java RMI (Remote Method Invocation) architecture allows an object running in one Java Virtual Machine to invoke methods on an object running in another JVM. The architecture consists of several components: the client, the server, the stub, the skeleton, and the RMI registry. The client holds a reference to the stub, which acts as a proxy for the remote object. When the client calls a method on the stub, the stub communicates with the skeleton on the server side (in older versions of Java) or directly with the remote object (in modern versions) using the RMI transport layer. The skeleton unmarshals the request and invokes the actual method on the remote object. The result is then sent back to the client through the same route. The RMI registry helps clients find the reference to remote objects using a name-based lookup.

Tasks of Stub and Skeleton

The stub is a client-side proxy object that represents the remote object. Its primary role is to forward method calls from the client to the remote server object by marshalling the method parameters into a network-friendly format. It also receives the response and returns it to the client.

The skeleton is a server-side object that was used in older versions of Java RMI (before Java 1.2). Its role was to receive the method invocation request from the stub, unmarshal the parameters, invoke the actual method on the remote object, and then marshal the result to send it back to the client. In modern Java RMI, the use of the skeleton has been removed, and the stub communicates directly with the remote object.