Complete Lesson: URL Mapping, GET and POST Parameters, JSON Input and JSON Output in Spring Boot

Complete Lesson: URL Mapping, GET and POST Parameters, JSON Input and JSON Output in Spring Boot

This lesson explains how Spring Boot maps URLs to controller methods, how GET and POST requests work, how to read query parameters, path variables, form values, JSON input, and how to return JSON responses cleanly from your APIs.

URL Mapping GET POST Path Variables Request Params JSON Input JSON Output

1. What URL mapping means

URL mapping means deciding which Java method should run for a particular request URL.

Example request:

GET /about

Matching controller method:

@GetMapping("/about")
public String about() {
    return "about";
}
When the browser requests /about, Spring Boot calls the about() method.

2. Parts of a web request

A request usually contains these pieces:

  • HTTP method: GET, POST, PUT, DELETE
  • URL path: /hello, /users/10
  • query parameters: ?name=Champak&city=Lucknow
  • headers
  • body: form data or JSON
Spring looks at these parts and decides which controller method should handle the request.

3. Main mapping annotations

The most common annotations are:

@RequestMapping(...)
@GetMapping(...)
@PostMapping(...)
@PutMapping(...)
@DeleteMapping(...)
@PatchMapping(...)

General style with @RequestMapping

@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
    return "Hello";
}

Shorter style with @GetMapping

@GetMapping("/hello")
public String hello() {
    return "Hello";
}

POST example

@PostMapping("/submit")
public String submit() {
    return "Submitted";
}
For most projects, use @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping directly.

4. Class-level and method-level mapping

You can put part of the URL on the class and the rest on each method.

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping
    public String allUsers() {
        return "All users";
    }

    @GetMapping("/active")
    public String activeUsers() {
        return "Active users";
    }
}

This creates these routes:

  • GET /api/users
  • GET /api/users/active
This helps keep controllers clean and organized.

5. GET requests

GET is usually used for:

  • reading data
  • showing pages
  • searching or filtering

Examples:

GET /products GET /products/10 GET /search?q=spring

6. GET query parameters with @RequestParam

Example URL:

/hello?name=Champak

The query parameter is:

  • key = name
  • value = Champak

Basic example

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(@RequestParam String name) {
        return "Hello " + name + "!";
    }
}

Default value

@GetMapping("/hello")
public String hello(@RequestParam(defaultValue = "World") String name) {
    return "Hello " + name + "!";
}

Now:

  • /helloHello World!
  • /hello?name=ChampakHello Champak!

Optional parameter

@GetMapping("/hello")
public String hello(@RequestParam(required = false) String name) {
    if (name == null || name.isBlank()) {
        return "Hello Guest!";
    }
    return "Hello " + name + "!";
}

Multiple GET parameters

@GetMapping("/search")
public String search(@RequestParam String keyword,
                     @RequestParam String city) {
    return "Searching for " + keyword + " in " + city;
}

7. Path variables with @PathVariable

Sometimes the value is part of the URL path itself.

Example:

/users/10

Use @PathVariable to read it.

@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable int id) {
        return "User id = " + id;
    }
}

Multiple path variables

@GetMapping("/{userId}/orders/{orderId}")
public String getOrder(@PathVariable int userId,
                       @PathVariable int orderId) {
    return "User " + userId + ", Order " + orderId;
}

8. Query parameter vs path variable

Use case Best choice
Specific resource /users/10@PathVariable
Filter or optional value /products?category=books@RequestParam
Sorting/searching /search?q=spring@RequestParam
Rule: identify resources with path variables, filter and search with query parameters.

9. POST requests

POST is usually used for:

  • submitting forms
  • creating new records
  • sending JSON in request bodies

POST data can come from:

  • form fields
  • request body
  • JSON payload

10. POST form parameters with @RequestParam

Suppose your HTML form looks like this:

<form action="/submit" method="post">
  <input name="name" />
  <input name="city" />
  <button type="submit">Send</button>
</form>

Read the values like this:

@Controller
public class FormController {

    @PostMapping("/submit")
    public String submit(@RequestParam String name,
                         @RequestParam String city,
                         Model model) {
        model.addAttribute("message", "Hello " + name + " from " + city);
        return "result";
    }
}
This is good for small forms, but larger forms are cleaner with object binding.

11. Form binding with objects using @ModelAttribute

Create a form DTO:

public class UserForm {
    private String name;
    private String city;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

Use it in the controller:

@Controller
public class FormController {

    @GetMapping("/form")
    public String form(Model model) {
        model.addAttribute("userForm", new UserForm());
        return "form";
    }

    @PostMapping("/form")
    public String submit(@ModelAttribute UserForm userForm, Model model) {
        model.addAttribute("message",
                "Hello " + userForm.getName() + " from " + userForm.getCity());
        return "result";
    }
}

Thymeleaf form:

<form th:action="@{/form}" th:object="${userForm}" method="post">
  <input type="text" th:field="*{name}" />
  <input type="text" th:field="*{city}" />
  <button type="submit">Submit</button>
</form>

12. Reading JSON input with @RequestBody

This is very important for APIs.

Suppose the client sends this JSON:

{
  "name": "Champak",
  "city": "Lucknow"
}

DTO class

public class UserRequest {
    private String name;
    private String city;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}

Controller

@RestController
@RequestMapping("/api/users")
public class UserApiController {

    @PostMapping
    public String createUser(@RequestBody UserRequest request) {
        return "Received " + request.getName() + " from " + request.getCity();
    }
}

Request example

POST /api/users
Content-Type: application/json

{
  "name": "Champak",
  "city": "Lucknow"
}
Spring automatically converts JSON into a Java object when you use @RequestBody.

13. Returning JSON

When you use @RestController, Spring automatically converts Java objects into JSON.

Response DTO

public class UserResponse {
    private String message;
    private String status;

    public UserResponse(String message, String status) {
        this.message = message;
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public String getStatus() {
        return status;
    }
}

Controller method

@RestController
@RequestMapping("/api/users")
public class UserApiController {

    @GetMapping("/sample")
    public UserResponse sample() {
        return new UserResponse("User fetched", "success");
    }
}

JSON response

{
  "message": "User fetched",
  "status": "success"
}

14. Read JSON and return JSON

This is one of the most common API patterns.

Request DTO

public class GreetingRequest {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Response DTO

public class GreetingResponse {
    private String message;

    public GreetingResponse(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

Controller

@RestController
@RequestMapping("/api")
public class GreetingApiController {

    @PostMapping("/greet")
    public GreetingResponse greet(@RequestBody GreetingRequest request) {
        String name = request.getName();

        if (name == null || name.isBlank()) {
            name = "World";
        }

        return new GreetingResponse("Hello " + name + "!");
    }
}

Request JSON

{
  "name": "Champak"
}

Response JSON

{
  "message": "Hello Champak!"
}

15. Using ResponseEntity for more control

ResponseEntity lets you control the status code, headers, and body.

@RestController
@RequestMapping("/api")
public class DemoApiController {

    @PostMapping("/greet")
    public ResponseEntity<GreetingResponse> greet(@RequestBody GreetingRequest request) {
        String name = request.getName();

        if (name == null || name.isBlank()) {
            return ResponseEntity.badRequest()
                    .body(new GreetingResponse("Name is required"));
        }

        return ResponseEntity.ok(new GreetingResponse("Hello " + name + "!"));
    }
}

This allows responses like:

  • 200 OK
  • 400 Bad Request
  • custom headers when needed

16. Validation with JSON input

Add validation annotations to the request DTO.

import jakarta.validation.constraints.NotBlank;

public class GreetingRequest {

    @NotBlank(message = "Name is required")
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Then validate it in the controller:

@PostMapping("/greet")
public GreetingResponse greet(@Valid @RequestBody GreetingRequest request) {
    return new GreetingResponse("Hello " + request.getName() + "!");
}
Validation helps make sure the API receives proper input before the method continues.

17. @Controller vs @RestController

Annotation Use for
@Controller HTML pages, Thymeleaf templates
@RestController APIs, JSON, text responses

Template example

@Controller
public class PageController {

    @GetMapping("/")
    public String home() {
        return "index";
    }
}

API example

@RestController
public class ApiController {

    @GetMapping("/api/hello")
    public String hello() {
        return "Hello API";
    }
}

18. Common mistakes

Mistake 1: Using @RestController for Thymeleaf pages

@RestController
public class PageController {
    @GetMapping("/")
    public String home() {
        return "index";
    }
}

This returns the text index instead of rendering the page.

Mistake 2: Duplicate route mappings

@GetMapping("/")
public String one() { ... }

@GetMapping("/")
public String two() { ... }

This causes an ambiguous mapping error.

Mistake 3: Using @RequestParam for JSON body

If the client sends JSON, use @RequestBody, not @RequestParam.

Mistake 4: Forgetting getters and setters in DTOs

Spring needs them to map JSON properly.

Rule: use @PathVariable for path values, @RequestParam for query/form values, and @RequestBody for JSON body input.

19. Terminal commands and what they do

Below is a practical list of terminal commands you are likely to use while building, running, testing, and debugging a Spring Boot project.

Go to your project folder

cd D:\springdemo

This moves the terminal into your project directory so Gradle commands run against the correct project.

See files in the current folder

dir

This lists the files and folders in the current directory in Windows PowerShell or Command Prompt.

Clean old build files

.\gradlew.bat clean

This removes the generated build output such as compiled classes and packaged jars from the build/ folder.

Build the project

.\gradlew.bat build

This compiles the code, runs tests, and packages the application.

Force dependency refresh

.\gradlew.bat build --refresh-dependencies

This tells Gradle to download dependencies again instead of relying only on its cache.

Run the application

.\gradlew.bat bootRun

This starts the Spring Boot application directly from source code.

Clean and run again

.\gradlew.bat clean bootRun

This first removes old build files and then starts the application again.

Run tests only

.\gradlew.bat test

This runs the test suite without building the full application artifact.

See detailed error output

.\gradlew.bat bootRun --stacktrace

This starts the app and prints the full Java stack trace if something goes wrong.

Show Gradle dependency tree

.\gradlew.bat dependencies

This shows all project dependencies and how they are brought into the project.

Check installed Java version

java -version

This shows which Java runtime is installed and being used.

Check Java compiler version

javac -version

This shows which Java compiler version is installed.

Run the generated jar manually

java -jar .\build\libs\your-app-name.jar

This runs the packaged Spring Boot jar after a successful build.

Open localhost in browser

http://localhost:8080/

This is not a terminal command, but it is the main URL you open in the browser after the app starts.

Open an API endpoint

http://localhost:8080/api/hello?name=Champak

This is an example browser or API test URL for checking whether a mapped endpoint works.

Most-used commands: clean, build, bootRun, and test.

20. File list and what each file does

Below is a useful list of common project files and folders in a Spring Boot application, with a short explanation of why each one matters.

File / Folder Explanation
build.gradle Gradle build file. It defines plugins, dependencies, Java version, and build behavior.
settings.gradle Defines the project name and Gradle settings for the root project.
gradlew Gradle wrapper script for Linux and macOS.
gradlew.bat Gradle wrapper script for Windows. This is the one you usually run on Windows.
gradle/wrapper/ Contains the Gradle wrapper files that allow the project to use a project-specific Gradle version.
src/main/java/ Main Java source code folder for application classes.
src/main/java/.../DemoApplication.java Main Spring Boot entry point. This contains the main method that starts the app.
src/main/java/.../controller/ Contains controller classes that map URLs to Java methods.
src/main/java/.../controller/PageController.java Usually handles HTML pages and Thymeleaf templates with @Controller.
src/main/java/.../controller/ApiController.java Usually handles JSON or text API responses with @RestController.
src/main/java/.../dto/ Contains DTO classes used to receive or return structured data such as forms or JSON.
src/main/java/.../dto/GreetingRequest.java Example request DTO for reading JSON input with @RequestBody.
src/main/java/.../dto/GreetingResponse.java Example response DTO for returning JSON from an API.
src/main/java/.../dto/UserForm.java Example form-backing object used with @ModelAttribute and Thymeleaf forms.
src/main/java/.../service/ Contains service classes where business logic is kept.
src/main/java/.../service/GreetingService.java Example service class that creates messages or handles reusable logic.
src/main/resources/ Main resources folder for templates, static assets, and configuration files.
src/main/resources/application.properties Application configuration file. Used for settings like port, application name, logging, and profiles.
src/main/resources/templates/ Contains Thymeleaf HTML templates.
src/main/resources/templates/index.html Home page template.
src/main/resources/templates/about.html About page template.
src/main/resources/templates/form.html Form page template for collecting input from the user.
src/main/resources/templates/result.html Page template used to display submitted or processed results.
src/main/resources/templates/fragments/ Stores reusable Thymeleaf fragments like header, footer, navbar, and common layout parts.
src/main/resources/templates/fragments/header.html Reusable header or navigation fragment.
src/main/resources/templates/fragments/footer.html Reusable footer fragment.
src/main/resources/static/ Contains CSS, JavaScript, and images served directly to the browser.
src/main/resources/static/css/style.css Main CSS file for page styling.
src/main/resources/static/js/app.js Main JavaScript file for client-side behavior.
src/main/resources/static/images/ Folder for logos, icons, and other image assets.
src/test/java/ Contains test classes for unit tests and integration tests.
src/test/java/.../HelloControllerTest.java Test class used to verify endpoint behavior.
build/ Generated build output folder. Created by Gradle. It usually contains compiled classes and jars.
.gradle/ Gradle working folder used internally for caching and build information.
Easy way to remember it:
Java code goes in src/main/java
HTML goes in src/main/resources/templates
CSS and JS go in src/main/resources/static
configuration goes in application.properties

21. Final summary

Case Example Annotation
Path value /users/10 @PathVariable
Query value /hello?name=Champak @RequestParam
Form POST value name=Champak @RequestParam or @ModelAttribute
JSON request body { "name": "Champak" } @RequestBody
JSON response returning a Java object from API automatic with @RestController
Best mental model:
@PathVariable → value from URL path
@RequestParam → value from query string or form fields
@RequestBody → value from JSON body
returning object from @RestController → JSON output

Once you understand these patterns, you can build both HTML-based web apps and JSON-based APIs much more confidently in Spring Boot.