Introduction to Web Development & Spring Boot


Table of Contents

How the Web Works — HTTP Request/Response Cycle

Before writing a single line of Spring Boot code, you need to understand what actually happens when you type a URL into your browser and press Enter. This is the foundation of everything you will build as a web developer.

The Journey of a Web Request

Imagine you open your browser and type https://www.google.com. Here is what happens behind the scenes:

Step 1: DNS Resolution

Your browser does not know where www.google.com lives. It needs an IP address — a numerical address like 142.250.80.4. So it asks a DNS (Domain Name System) server to translate the human-readable domain name into an IP address. Think of DNS as a phone book for the internet.

Step 2: TCP Connection

Once the browser knows the IP address, it establishes a TCP (Transmission Control Protocol) connection with the server. This is like making a phone call — both sides agree to start communicating.

Step 3: HTTP Request

Now the browser sends an HTTP request to the server. HTTP stands for HyperText Transfer Protocol — it is the language that browsers and servers use to talk to each other.

A simple HTTP request looks like this:

GET /search?q=spring+boot HTTP/1.1
Host: www.google.com
Accept: text/html
User-Agent: Mozilla/5.0

Let us break this down line by line:

  • GET — This is the HTTP methodGET means “I want to retrieve something.” There are other methods like POST (send data), PUT (update data), and DELETE (remove data). We will use all of these throughout this series.
  • /search?q=spring+boot — This is the path (also called the URI). It tells the server exactly what resource you want. The part after ? is a query parameter.
  • HTTP/1.1 — This is the protocol version.
  • HostAcceptUser-Agent — These are headers. They provide extra information about the request, like which website you want to reach, what format you can accept, and what browser you are using.

Step 4: Server Processing

The server receives the request, processes it (runs some code, maybe queries a database), and prepares a response.

Step 5: HTTP Response

The server sends back an HTTP response:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 12345

<!DOCTYPE html>
<html>
  <body>
    <h1>Search Results</h1>
    ...
  </body>
</html>

Here is what each part means:

  • OK — This is the status code200 means everything went well. You will encounter many status codes: 404 (not found), 500 (server error), 201 (created), 401 (unauthorized), and more.
  • Content-Type: text/html — This header tells the browser that the response body is HTML.
  • The rest is the response body — the actual content (HTML, JSON, an image, etc.).

Step 6: Browser Rendering

The browser receives the HTML and renders it on your screen. If the HTML references CSS files, JavaScript files, or images, the browser sends additional HTTP requests to fetch those too.

Why This Matters for You

As a Spring Boot developer, your job is to write the code that runs in Step 4 — the server processing. You will write code that:

  • Listens for incoming HTTP requests
  • Reads the request method, path, headers, and body
  • Executes business logic (calculations, database queries, validations)
  • Returns an HTTP response with the appropriate status code and body

This is the core of web development. Everything else — frameworks, databases, security — is tooling that helps you do this more efficiently.


Client-Server Architecture Overview

Now that you understand the HTTP request/response cycle, let us zoom out and look at the bigger picture: the client-server architecture.

What is a Client?

A client is any application that sends requests to a server. The most common client is a web browser (Chrome, Firefox, Safari). But clients can also be:

  • A mobile app (Android, iOS)
  • Another server (server-to-server communication)
  • A command-line tool like curl
  • A desktop application
  • A JavaScript frontend framework (React, Angular, Vue)

What is a Server?

A server is an application that listens for incoming requests, processes them, and sends back responses. In our case, the server will be a Spring Boot application running on a machine (your laptop during development, a cloud server in production).

The Separation of Concerns

The beauty of client-server architecture is the separation of concerns:

  • The client is responsible for the user interface — displaying data, handling user input, and making the experience look nice.
  • The server is responsible for business logic, data storage, security, and serving data to the client.

This separation means you can have multiple types of clients (a web app, a mobile app, and a desktop app) all talking to the same server. The server does not care what the client looks like — it just receives requests and sends responses.

How They Communicate

In modern web development, the most common communication format between client and server is JSON (JavaScript Object Notation). Instead of returning HTML from your server, you return JSON data, and the client decides how to display it.

Here is an example. A client sends a request:

GET /api/users/42 HTTP/1.1
Host: myapp.com
Accept: application/json

The server responds with JSON:

{
  "id": 42,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "ADMIN"
}

The client (whether it is a React web app or an Android app) receives this JSON and renders it however it wants. The React app might show it in a table. The Android app might show it in a card. Same data, different presentations.

This pattern — where the server provides data through an API and the client handles the presentation — is called a REST API (Representational State Transfer). You will build REST APIs throughout this entire series.

A Quick Comparison with Your Java Experience

If you have built Java desktop applications (Swing, JavaFX), you wrote everything in one place — the UI code and the logic were all in the same project. In web development, we split them apart:

Desktop AppWeb App
UI + Logic in one projectClient (frontend) and Server (backend) are separate
Runs on user’s machineServer runs remotely, client runs in browser
Direct method callsCommunication via HTTP
Java objects in memoryData exchanged as JSON

In this series, we focus on the server side — building the Spring Boot backend that exposes a REST API. The client could be anything: a browser, Postman (a tool for testing APIs), or a frontend framework.


What is a Web Framework and Why Do We Need One?

The Hard Way: Raw Java HTTP Server

Java has a built-in HTTP server. You could technically write a web application without any framework:

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;
import java.io.*;
import java.net.InetSocketAddress;

public class RawServer {
    public static void main(String[] args) throws IOException {
        // Create an HTTP server listening on port 8080
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);

        // Define a handler for the "/hello" path
        server.createContext("/hello", new HttpHandler() {
            @Override
            public void handle(HttpExchange exchange) throws IOException {
                // Prepare the response
                String response = "{\"message\": \"Hello, World!\"}";

                // Set response headers
                exchange.getResponseHeaders().set("Content-Type", "application/json");

                // Send the response with status code 200
                exchange.sendResponseHeaders(200, response.getBytes().length);

                // Write the response body
                OutputStream os = exchange.getResponseBody();
                os.write(response.getBytes());
                os.close();
            }
        });

        // Start the server
        server.start();
        System.out.println("Server running on port 8080");
    }
}

This code creates a simple HTTP server that responds with a JSON message when you visit http://localhost:8080/hello. It works, but look at all the things you had to do manually:

  • Create the server and bind it to a port
  • Register each URL path with a handler
  • Manually set headers
  • Manually convert the response to bytes
  • Manually manage the output stream

Now imagine you need to build a real application with 50 endpoints, database access, authentication, input validation, error handling, logging, and more. You would spend months writing boilerplate code before you even start on your actual business logic.

The Easy Way: Use a Framework

web framework is a collection of pre-built tools and conventions that handle the repetitive parts of web development so you can focus on what makes your application unique.

Here is the same “Hello World” endpoint written with Spring Boot:

@RestController
public class HelloController {

    @GetMapping("/hello")
    public Map<String, String> hello() {
        return Map.of("message", "Hello, World!");
    }
}

That is it. Three lines of actual code. Spring Boot handles everything else:

  • Starting the HTTP server
  • Routing the request to the right method
  • Converting the Map to JSON automatically
  • Setting the correct Content-Type header
  • Managing the response output stream

Do not worry if the annotations (@RestController@GetMapping) look unfamiliar right now. We will explain every single one in detail. The point here is to show you why frameworks exist — they eliminate boilerplate and let you focus on business logic.

What a Web Framework Typically Provides

Most web frameworks, including Spring Boot, provide these features out of the box:

  • Routing: Mapping URLs to specific handler methods
  • Request/Response handling: Parsing incoming data and formatting outgoing data
  • Database access: Tools to read and write data from a database
  • Security: Authentication (who are you?) and authorization (what can you do?)
  • Validation: Checking that incoming data meets your requirements
  • Error handling: Returning meaningful error messages
  • Testing: Tools to test your application without deploying it
  • Configuration: Managing settings for different environments (development, staging, production)

Introduction to Spring Ecosystem

A Brief History

The Spring Framework was created by Rod Johnson in 2003. At that time, building Java web applications meant using Java EE (Enterprise Edition), which was notoriously complex and heavy. Spring was born as a lighter, simpler alternative.

Over the years, Spring grew into a massive ecosystem with many sub-projects. Here are the ones you will encounter most often:

  • Spring Framework — The core foundation. Provides Dependency Injection (IoC container), AOP (Aspect-Oriented Programming), and basic web support.
  • Spring MVC — The web layer. Handles HTTP requests and responses using the Model-View-Controller pattern.
  • Spring Data — Simplifies database access. Spring Data JPA (which we will use with MariaDB) lets you work with databases using Java objects instead of raw SQL.
  • Spring Security — Handles authentication and authorization.
  • Spring Boot — The game changer. Makes it incredibly easy to create Spring applications with minimal configuration.

Spring Framework vs Spring Boot

This distinction is crucial, and many beginners confuse the two.

Spring Framework is the underlying technology — the engine. It provides powerful features but requires significant manual configuration. In the early days, you had to write hundreds of lines of XML to configure a Spring application:

<!-- Old-style Spring configuration (you do NOT need to write this) -->
<beans>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="com.example.model"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <!-- ... and many more beans ... -->
</beans>

Spring Boot is a layer on top of Spring Framework that dramatically reduces this configuration. It uses sensible defaults and auto-configuration to get you started with almost zero setup. The same database configuration in Spring Boot looks like this:

# application.properties — that's ALL you need
spring.datasource.url=jdbc:mariadb://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password

Spring Boot looks at what libraries are on your classpath and automatically configures them. If it sees a MariaDB driver, it auto-configures a DataSource. If it sees Spring MVC, it auto-configures a web server. This is the magic of auto-configuration.

An Analogy

Think of it this way:

  • Spring Framework is like buying all the parts to build a car — engine, wheels, transmission, seats — and assembling them yourself.
  • Spring Boot is like buying a car that comes fully assembled with a standard configuration. You can still customize it, but it works right out of the factory.

Throughout this series, when we say “Spring Boot,” we are using Spring Boot on top of Spring Framework, Spring MVC, Spring Data JPA, and Spring Security. Spring Boot ties them all together.


What Spring Boot Solves — Convention over Configuration

The Philosophy

Spring Boot follows a principle called Convention over Configuration. This means:

If there is a sensible default, use it. Only require the developer to configure things that are unique to their application.

Here are the key problems Spring Boot solves:

Problem 1: Dependency Management Hell

In a traditional Spring project, you had to manually find and manage dozens of compatible library versions. One wrong version could break everything.

Spring Boot’s solution: Starter dependencies.

Instead of adding 10 individual libraries for web development, you add one starter:

<!-- This single dependency pulls in everything you need for a web app -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

This one starter includes Spring MVC, Jackson (for JSON), an embedded Tomcat server, validation, and logging — all with compatible versions that are tested together.

Problem 2: XML Configuration Overload

As you saw in the previous section, traditional Spring required mountains of XML configuration.

Spring Boot’s solution: Auto-configuration and annotations.

Spring Boot scans your project, detects what libraries are available, and configures them automatically. You only need to provide the information that Spring Boot cannot guess (like your database URL).

Problem 3: Server Setup and Deployment

Traditional Java web applications needed to be packaged as a WAR file and deployed to an external application server (Tomcat, JBoss, WebLogic). Setting up and managing these servers was a job in itself.

Spring Boot’s solution: Embedded server.

Spring Boot includes an embedded Tomcat (or Jetty, or Undertow) server inside your application. You just run your application like any normal Java program:

java -jar myapp.jar

No external server installation. No WAR file deployment. Your application IS the server.

Problem 4: Environment-Specific Configuration

Different environments (development, testing, production) need different settings (database URLs, API keys, logging levels).

Spring Boot’s solution: Profiles and externalized configuration.

# application-dev.properties
spring.datasource.url=jdbc:mariadb://localhost:3306/mydb_dev
logging.level.root=DEBUG

# application-prod.properties
spring.datasource.url=jdbc:mariadb://prod-server:3306/mydb_prod
logging.level.root=WARN

You activate a profile with a simple flag:

java -jar myapp.jar --spring.profiles.active=prod


Setting Up the Development Environment

Before we create our first project, let us make sure your development environment is ready. You need three things: a JDK, a build tool, and an IDE.

JDK (Java Development Kit)

You should already have Java installed since you know Java. For Spring Boot 3.x (which we are using), you need Java 17 or higher.

Check your Java version:

java -version

You should see something like:

openjdk version "17.0.x" 2024-xx-xx

If you need to install or upgrade, download from Adoptium (recommended) or Oracle JDK.

Build Tool: Maven

Spring Boot supports both Maven and Gradle. In this series, we will use Maven because it is more widely used in the Spring ecosystem and has straightforward XML-based configuration.

If you have used Java before, you may already have Maven installed. Check with:

mvn -version

If not installed, download from maven.apache.org and add it to your system PATH.

Note: If you are more comfortable with Gradle, everything in this series can be done with Gradle too. The Spring Initializr (next section) generates both Maven and Gradle projects.

IDE: IntelliJ IDEA

While you can use any IDE or text editor, IntelliJ IDEA is the best IDE for Spring Boot development. The Community Edition is free and sufficient for this series, but the Ultimate Edition has extra Spring-specific features.

Other options:

  • Visual Studio Code with the Spring Boot Extension Pack
  • Eclipse / Spring Tool Suite (STS)

For IntelliJ IDEA, install these helpful plugins (most are included by default):

  • Spring Boot (Ultimate only)
  • Maven Helper
  • Lombok (we will use it later in the series)

Optional but Recommended: Postman or HTTPie

Since we are building REST APIs, you need a way to test them. Your browser can only send GET requests easily. For POSTPUT, and DELETE, you need a tool:

  • Postman — A GUI tool for testing APIs. Download from postman.com.
  • curl — A command-line tool (already installed on Mac/Linux).
  • HTTPie — A more user-friendly command-line alternative to curl.

We will use Postman in our examples, but any of these tools will work.


Creating Your First Spring Boot Project with Spring Initializr

Now for the exciting part — let us create your first Spring Boot project.

What is Spring Initializr?

Spring Initializr is a web-based tool (and also integrated into IntelliJ IDEA) that generates a Spring Boot project skeleton for you. Instead of creating all the files and folders manually, you fill out a form, click a button, and download a ready-to-use project.

Using the Web Interface

Go to start.spring.io and fill out the form:

FieldValueExplanation
ProjectMavenOur build tool
LanguageJavaOur programming language
Spring Boot3.3.x (latest stable)The Spring Boot version
Groupcom.exampleYour organization’s domain in reverse (like a Java package)
Artifactblog-apiThe project name
Nameblog-apiThe display name
DescriptionBlog REST API with Spring Boot and MariaDBA short description
Package namecom.example.blogapiThe base Java package
PackagingJarWe want an executable JAR (not WAR)
Java17Our Java version

Adding Dependencies

Click “Add Dependencies” and add:

  • Spring Web — Provides Spring MVC for building REST APIs and includes an embedded Tomcat server.

For now, that is all we need. We will add more dependencies (MariaDB, JPA, Security, etc.) in later lectures.

Click “Generate” to download a ZIP file. Extract it to your preferred workspace directory.

Using IntelliJ IDEA (Alternative Method)

If you are using IntelliJ IDEA Ultimate, you can create the project directly from the IDE:

  1. Go to File → New → Project
  2. Select Spring Initializr on the left
  3. Fill in the same fields as above
  4. Select Spring Web dependency
  5. Click Create

IntelliJ will generate the project and open it automatically.


Understanding the Project Structure

Open the generated project in your IDE. You will see this structure:

blog-api/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── blogapi/
│   │   │               └── BlogApiApplication.java
│   │   └── resources/
│   │       ├── static/
│   │       ├── templates/
│   │       └── application.properties
│   └── test/
│       └── java/
│           └── com/
│               └── example/
│                   └── blogapi/
│                       └── BlogApiApplicationTests.java
├── pom.xml
├── mvnw
├── mvnw.cmd
└── .gitignore

Let us examine each important file and folder:

pom.xml — The Project Configuration

This is Maven’s configuration file. It defines your project’s dependencies, plugins, and build settings.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- This is the parent POM — it provides default configurations
         and dependency versions for Spring Boot projects -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.0</version>
        <relativePath/>
    </parent>

    <!-- Your project's coordinates — these uniquely identify your project -->
    <groupId>com.example</groupId>
    <artifactId>blog-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>blog-api</name>
    <description>Blog REST API with Spring Boot and MariaDB</description>

    <!-- Java version -->
    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- Spring Web Starter: includes Spring MVC, embedded Tomcat,
             Jackson (JSON library), and more -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Notice: no version specified! The parent POM manages versions
             for all Spring Boot starters, so they are always compatible -->

        <!-- Spring Boot Test Starter: includes JUnit 5, Mockito,
             MockMvc, and other testing tools -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- This plugin packages your app as an executable JAR
                 with an embedded server -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Key observations:

  • The spring-boot-starter-parent manages all dependency versions for you. You do not need to specify versions for Spring Boot starters.
  • spring-boot-starter-web is a single dependency that brings in everything needed for web development.
  • The spring-boot-maven-plugin is what allows you to run the app with mvn spring-boot:run and package it as an executable JAR.

BlogApiApplication.java — The Entry Point

package com.example.blogapi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BlogApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(BlogApiApplication.class, args);
    }
}

This is the heart of your application. Let us understand every part:

  • @SpringBootApplication — This single annotation is actually a shortcut for three annotations combined:
    • @SpringBootConfiguration — Marks this class as a configuration class (like @Configuration)
    • @EnableAutoConfiguration — Tells Spring Boot to automatically configure beans based on the libraries on your classpath
    • @ComponentScan — Tells Spring to scan the current package and all sub-packages for components (@Controller@Service@Repository, etc.)
  • SpringApplication.run(...) — This method bootstraps the entire application. It creates the Spring Application Context, performs auto-configuration, starts the embedded web server, and begins listening for HTTP requests.

This is the method that turns your regular Java program into a web server. With just one line, you go from a main() method to a fully running web application.

application.properties — Configuration File

# This file is currently empty.
# You will add configuration here as your application grows.
# Examples:
# server.port=8080
# spring.datasource.url=jdbc:mariadb://localhost:3306/mydb

This is where you configure your application’s behavior. Spring Boot reads this file at startup and applies the settings. We will populate it in later lectures when we add the database, security, and other features.

Other Folders

  • src/main/resources/static/ — For static files (HTML, CSS, JavaScript, images). We will not use this since we are building a REST API, not a traditional website.
  • src/main/resources/templates/ — For server-side HTML templates (Thymeleaf, FreeMarker). We will not use this either.
  • src/test/ — For test classes. We will write tests in Lecture 15.
  • mvnw and mvnw.cmd — The Maven Wrapper. These scripts let anyone build the project without having Maven installed globally. Use ./mvnw (Mac/Linux) or mvnw.cmd (Windows) instead of mvn.

Running the Application & The Embedded Server

Starting the Application

You have two ways to run your Spring Boot application:

Method 1: From the IDE

In IntelliJ IDEA, open BlogApiApplication.java and click the green “Run” button next to the main method. This is the most convenient way during development.

Method 2: From the Terminal

Navigate to your project directory and run:

# Using Maven Wrapper (recommended — no Maven installation needed)
./mvnw spring-boot:run

# Or if you have Maven installed globally
mvn spring-boot:run

What Happens When You Run It

When you execute the application, you will see output like this in the console:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.0)

2024-01-15T10:30:00.123  INFO --- Starting BlogApiApplication
2024-01-15T10:30:01.456  INFO --- Tomcat initialized with port 8080 (http)
2024-01-15T10:30:01.789  INFO --- Starting service [Tomcat]
2024-01-15T10:30:01.890  INFO --- Starting Servlet engine: [Apache Tomcat/10.1.x]
2024-01-15T10:30:02.345  INFO --- Tomcat started on port 8080 (http)
2024-01-15T10:30:02.456  INFO --- Started BlogApiApplication in 2.5 seconds

Let us read this output:

  1. The Spring Boot banner appears (the ASCII art).
  2. Spring Boot starts initializing — scanning for components, running auto-configuration.
  3. Tomcat is initialized on port 8080. This is the embedded web server. You did not install Tomcat — it came bundled with spring-boot-starter-web.
  4. The application is ready and listening for HTTP requests on http://localhost:8080.

Testing It

Open your browser and go to http://localhost:8080. You will see a “Whitelabel Error Page” with a 404 status:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

There was an unexpected error (type=Not Found, status=404).

This is actually a good sign! It means your server is running and responding to requests. The 404 error just means we have not defined any endpoints yet. We will fix that in the next section.

Changing the Port

By default, Spring Boot runs on port 8080. If that port is already in use, you can change it in application.properties:

server.port=9090

Now the application will start on http://localhost:9090 instead.

The Embedded Server Explained

In traditional Java web development, you would:

  1. Install an application server (Tomcat, JBoss, WildFly) on your machine
  2. Package your application as a WAR file
  3. Deploy the WAR file to the application server
  4. Start the application server

With Spring Boot’s embedded server approach:

  1. Your application includes the server
  2. You run the application directly: java -jar blog-api.jar
  3. Done

This is a fundamental shift. Your application is self-contained and portable. You can run it anywhere Java is installed — on your laptop, a virtual machine, a Docker container, or a cloud platform.


Hands-on: “Hello World” REST Endpoint

Time to write your first real Spring Boot code. We are going to create a REST endpoint that returns a JSON response.

Step 1: Create the Controller Class

In your IDE, create a new Java class in the com.example.blogapi package:

File: src/main/java/com/example/blogapi/HelloController.java

package com.example.blogapi;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

// This annotation tells Spring that this class handles HTTP requests
// and that every method's return value should be written directly
// to the HTTP response body (as JSON, by default).
@RestController
public class HelloController {

    // This annotation maps HTTP GET requests for "/hello" to this method.
    // When someone visits http://localhost:8080/hello, this method runs.
    @GetMapping("/hello")
    public Map<String, String> hello() {
        // We return a Map, and Spring Boot automatically converts it to JSON.
        // No manual JSON conversion needed!
        Map<String, String> response = new HashMap<>();
        response.put("message", "Hello, World!");
        response.put("framework", "Spring Boot");
        return response;
    }

    // This endpoint demonstrates how to accept query parameters.
    // Example: http://localhost:8080/greet?name=Alice
    //
    // @RequestParam tells Spring to extract the "name" parameter from the URL.
    // The defaultValue ensures the app won't crash if "name" is not provided.
    @GetMapping("/greet")
    public Map<String, Object> greet(
            @RequestParam(defaultValue = "World") String name) {

        Map<String, Object> response = new HashMap<>();
        response.put("message", "Hello, " + name + "!");
        response.put("timestamp", LocalDateTime.now().toString());
        return response;
    }

    // This endpoint returns server status information.
    // It's a common pattern to have a /health or /status endpoint
    // that monitoring tools can check.
    @GetMapping("/status")
    public Map<String, Object> status() {
        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("application", "Blog API");
        response.put("javaVersion", System.getProperty("java.version"));
        response.put("timestamp", LocalDateTime.now().toString());
        return response;
    }
}

Step 2: Understanding the Code

Let us go through every annotation and concept:

@RestController

This annotation combines two things:

  • @Controller — Marks the class as a Spring MVC controller (a component that handles HTTP requests)
  • @ResponseBody — Tells Spring to write the return value directly to the HTTP response body

Without @ResponseBody, Spring would try to find an HTML template to render. With @RestController, it knows to convert the return value to JSON and send it back.

@GetMapping("/hello")

This maps HTTP GET requests to the /hello URL path to the annotated method. There are similar annotations for other HTTP methods:

  • @PostMapping — for POST requests
  • @PutMapping — for PUT requests
  • @DeleteMapping — for DELETE requests
  • @PatchMapping — for PATCH requests

We will use all of these in Lecture 3 when we build a full CRUD API.

@RequestParam

This annotation binds a query parameter from the URL to a method parameter. When someone visits /greet?name=Alice, Spring extracts the value "Alice" and passes it to the name parameter.

The defaultValue = "World" means that if someone visits /greet without the name parameter, the value will default to "World".

Return value → JSON conversion

Notice we are returning Map<String, String> and Map<String, Object>. Spring Boot uses a library called Jackson (included in spring-boot-starter-web) to automatically convert Java objects to JSON. This is called serialization. Later in the series, we will return custom Java classes instead of Maps, and Jackson will serialize them the same way.

Step 3: Restart and Test

Stop the running application (press the red “Stop” button in your IDE, or press Ctrl+C in the terminal) and start it again. Spring Boot needs to restart to pick up the new controller.

Tip: In later development, you can add spring-boot-devtools dependency for automatic restarts when code changes. For now, manual restart is fine.

Now test each endpoint:

Test 1: Using your browser

Open http://localhost:8080/hello in your browser. You should see:

{
  "message": "Hello, World!",
  "framework": "Spring Boot"
}

Test 2: Using curl (command line)

# Test the /hello endpoint
curl http://localhost:8080/hello

# Test the /greet endpoint with a name parameter
curl http://localhost:8080/greet?name=Alice

# Test the /greet endpoint without a name parameter (uses default)
curl http://localhost:8080/greet

# Test the /status endpoint
curl http://localhost:8080/status

Test 3: Using Postman

  1. Open Postman
  2. Create a new request
  3. Set the method to GET
  4. Enter http://localhost:8080/hello as the URL
  5. Click Send
  6. You should see the JSON response in the bottom panel

Step 4: Experiment

Try these exercises to reinforce what you have learned:

  1. Add a new endpoint: Create a @GetMapping("/about") method that returns information about the blog API (name, version, author).
  2. Multiple parameters: Create a @GetMapping("/add") that accepts two query parameters (a and b) and returns their sum. For example, /add?a=5&b=3 should return {"result": 8}.
  3. Change the port: Modify application.properties to run the server on port 3000 and verify it works.

Here is the solution for exercise 2 to check your work:

@GetMapping("/add")
public Map<String, Object> add(
        @RequestParam int a,
        @RequestParam int b) {

    Map<String, Object> response = new HashMap<>();
    response.put("a", a);
    response.put("b", b);
    response.put("result", a + b);
    return response;
}

Notice that Spring automatically converts the query parameter strings to int values. If someone sends a non-numeric value, Spring will return a 400 Bad Request error automatically.


Summary

In this first lecture, you have covered a lot of ground:

  • How the web works: Browsers send HTTP requests, servers process them and return HTTP responses. As a Spring Boot developer, you write the server-side processing code.
  • Client-server architecture: The client handles the UI, the server handles the data and logic. They communicate via HTTP, usually exchanging JSON.
  • Why we use frameworks: Frameworks like Spring Boot eliminate boilerplate code so you can focus on your application’s unique logic.
  • Spring ecosystem: Spring Framework is the engine, Spring Boot is the ready-to-drive car built on that engine.
  • Convention over configuration: Spring Boot provides smart defaults — embedded servers, starter dependencies, auto-configuration, and profiles.
  • Project setup: Spring Initializr generates a complete project structure. The pom.xml manages dependencies, BlogApiApplication.java is the entry point, and application.properties holds configuration.
  • Your first REST endpoint: Using @RestController and @GetMapping, you can create endpoints that return JSON with just a few lines of code.

What is Next

In Lecture 2, we will dive deep into Dependency Injection — the most important concept in the Spring ecosystem. You will learn how Spring manages objects (beans) for you and why this makes your code more modular, testable, and maintainable. This is the concept that unlocks everything else in Spring Boot.


Quick Reference

ConceptDescription
HTTPProtocol for client-server communication
REST APIAn API that uses HTTP methods to perform CRUD operations
Spring BootAn opinionated framework built on Spring Framework for rapid development
@SpringBootApplicationThe main annotation that enables auto-configuration and component scanning
@RestControllerMarks a class as a REST API controller
@GetMappingMaps a URL path to a method for HTTP GET requests
@RequestParamBinds a URL query parameter to a method parameter
application.propertiesThe main configuration file
pom.xmlMaven project configuration and dependency management
Embedded TomcatThe built-in web server included with spring-boot-starter-web

Leave a Reply

Your email address will not be published. Required fields are marked *