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.
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";
}
/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
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";
}
@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/usersGET /api/users/active
5. GET requests
GET is usually used for:
- reading data
- showing pages
- searching or filtering
Examples:
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:
/hello→Hello World!/hello?name=Champak→Hello 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 |
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";
}
}
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"
}
@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 OK400 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() + "!");
}
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.
@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.
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. |
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 |
@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.