Building Web Controllers

Back

Loading concept...

๐Ÿฐ Building Web Controllers in Spring

The Story of the Royal Mail Room


๐ŸŽญ Our Magical Metaphor

Imagine a grand castle that receives letters from people all over the kingdom. Every letter needs to go to the right person, get answered, and be sent back. This is exactly how Spring Web Controllers work!

  • The Castle = Your Spring Application
  • The Mail Room = DispatcherServlet
  • Delivery Workers = Controllers
  • Letter Instructions = Annotations
  • Opening Letters = Request Data Extraction
  • Writing Replies = Response Handling

๐Ÿ“ฌ Part 1: The DispatcherServlet - The Head Mail Sorter

What Is It?

Think of the DispatcherServlet as the HEAD OF THE MAIL ROOM. Every single letter (HTTP request) that arrives at the castle MUST pass through this person first.

What Does It Do?

Letter arrives โ†’ Head Sorter reads address โ†’
Finds right worker โ†’ Worker writes reply โ†’
Head Sorter sends it back

The Magic Flow

graph TD A["๐Ÿ“ฉ Request Arrives"] --> B["๐Ÿง‘โ€๐Ÿ’ผ DispatcherServlet"] B --> C["๐Ÿ“‹ Find Right Controller"] C --> D["โœ๏ธ Controller Does Work"] D --> E["๐Ÿ“ค Response Goes Back"] E --> F["๐Ÿ‘ค User Gets Answer"]

Simple Example

When you type www.myshop.com/products in your browser:

  1. DispatcherServlet catches this request
  2. Looks at /products and thinks: โ€œWho handles products?โ€
  3. Finds ProductController
  4. Sends the request there
  5. Gets the response and sends it to you

You never see DispatcherServlet. It works silently behind the scenes!


๐Ÿ—๏ธ Part 2: MVC Architecture - The Three Best Friends

Meet the Team

Model - View - Controller

Think of them as three friends working together to answer every letter:

Friend Job Castle Role
Model Carries data The messenger bag
View Makes things pretty The calligrapher
Controller Makes decisions The brain

How They Work Together

graph TD A["๐Ÿ‘ค User Request"] --> B["๐ŸŽฎ Controller"] B --> C["๐Ÿ“ฆ Model - Gets Data"] C --> D["๐ŸŽจ View - Makes Pretty"] D --> E["๐Ÿ‘ค User Sees Page"]

Real Example

User wants to see their profile:

  1. Controller receives request: โ€œShow profile!โ€
  2. Model fetches data: name, email, photo
  3. View creates HTML page with that data
  4. User sees beautiful profile page!
@Controller
public class ProfileController {

    @GetMapping("/profile")
    public String showProfile(Model model) {
        // Model carries the data
        model.addAttribute("name", "Alex");
        model.addAttribute("email", "alex@mail.com");

        // View name to display
        return "profile-page";
    }
}

๐Ÿ‘ท Part 3: Controller Types - Different Workers for Different Jobs

Two Types of Mail Workers

1. Regular Controller (@Controller)

  • Returns web pages (HTML)
  • Good for websites people visit
  • Works with Views (templates)
@Controller
public class WebsiteController {

    @GetMapping("/home")
    public String homePage() {
        return "home"; // Returns home.html
    }
}

2. REST Controller (@RestController)

  • Returns data (JSON/XML)
  • Good for mobile apps & APIs
  • No views needed!
@RestController
public class ApiController {

    @GetMapping("/api/users")
    public List<User> getUsers() {
        return userService.findAll();
        // Returns JSON data directly
    }
}

Quick Comparison

Feature @Controller @RestController
Returns HTML pages JSON/XML data
Used for Websites APIs, Mobile apps
Needs Views? Yes No

Secret Tip! ๐Ÿคซ

@RestController = @Controller + @ResponseBody

Itโ€™s just a shortcut!


๐Ÿท๏ธ Part 4: Request Mapping - Address Labels on Letters

The Big Boss: @RequestMapping

This tells Spring: โ€œSend requests from THIS address to THIS methodโ€

@RequestMapping("/shop")
public class ShopController {
    // All paths start with /shop
}

The Shortcut Family

Instead of writing long annotations, use these shortcuts:

Annotation What It Means Use When
@GetMapping GET request Reading data
@PostMapping POST request Creating data
@PutMapping PUT request Updating data
@DeleteMapping DELETE request Deleting data
@PatchMapping PATCH request Partial update

Examples That Make Sense

@RestController
@RequestMapping("/books")
public class BookController {

    @GetMapping
    public List<Book> getAllBooks() {
        // GET /books
    }

    @GetMapping("/{id}")
    public Book getBook(@PathVariable Long id) {
        // GET /books/5
    }

    @PostMapping
    public Book createBook(@RequestBody Book book) {
        // POST /books
    }

    @DeleteMapping("/{id}")
    public void deleteBook(@PathVariable Long id) {
        // DELETE /books/5
    }
}

Path Variables - Names in the Address

Use {curlyBraces} to capture parts of the URL:

@GetMapping("/users/{userId}/posts/{postId}")
public Post getPost(
    @PathVariable Long userId,
    @PathVariable Long postId) {
    // URL: /users/42/posts/7
    // userId = 42, postId = 7
}

๐Ÿ“จ Part 5: Request Data Extraction - Opening the Letters

Where Does Data Come From?

Data can arrive in many ways. Spring has tools to catch ALL of them!

graph TD A["๐Ÿ“จ Incoming Request"] --> B["URL Path"] A --> C["Query Parameters"] A --> D["Request Body"] A --> E["Headers"] A --> F["Cookies"]

1. @PathVariable - Data in the URL Path

// URL: /products/laptop/reviews/5
@GetMapping("/products/{product}/reviews/{reviewId}")
public Review getReview(
    @PathVariable String product,
    @PathVariable Long reviewId) {
    // product = "laptop"
    // reviewId = 5
}

2. @RequestParam - Data After the ?

// URL: /search?keyword=phone&page=2
@GetMapping("/search")
public List<Product> search(
    @RequestParam String keyword,
    @RequestParam(defaultValue = "1") int page) {
    // keyword = "phone"
    // page = 2
}

Optional parameters:

@RequestParam(required = false) String filter

3. @RequestBody - Data Inside the Letter

For POST/PUT requests with JSON data:

@PostMapping("/users")
public User createUser(@RequestBody User user) {
    // JSON automatically becomes User object!
    // {"name": "Alex", "email": "alex@mail.com"}
    // โ†’ User(name="Alex", email="alex@mail.com")
}

4. @RequestHeader - Info on the Envelope

@GetMapping("/secure-data")
public Data getData(
    @RequestHeader("Authorization") String token,
    @RequestHeader("Accept-Language") String lang) {
    // Read special instructions!
}

5. @CookieValue - Saved Notes

@GetMapping("/preferences")
public Settings getSettings(
    @CookieValue("theme") String theme) {
    // Read saved preferences
}

All Together Now!

@PostMapping("/orders/{orderId}/items")
public OrderItem addItem(
    @PathVariable Long orderId,
    @RequestParam boolean express,
    @RequestBody Item item,
    @RequestHeader("User-Id") Long userId) {
    // All data extracted automatically!
}

๐Ÿ“ค Part 6: Request & Response Handling - The Complete Story

The Request Journey

graph TD A["๐ŸŒ Browser/App"] -->|HTTP Request| B["DispatcherServlet"] B -->|Route| C["Controller Method"] C -->|Process| D["Service Layer"] D -->|Fetch| E["Database"] E -->|Data| D D -->|Result| C C -->|Response| B B -->|HTTP Response| A

Response Types

1. Return a View (HTML Page)

@Controller
public class PageController {

    @GetMapping("/welcome")
    public String welcome(Model model) {
        model.addAttribute("message", "Hello!");
        return "welcome"; // โ†’ welcome.html
    }
}

2. Return Data (JSON)

@RestController
public class ApiController {

    @GetMapping("/api/user")
    public User getUser() {
        return new User("Alex", "alex@mail.com");
        // โ†’ {"name":"Alex","email":"alex@mail.com"}
    }
}

3. Return ResponseEntity (Full Control)

@GetMapping("/api/product/{id}")
public ResponseEntity<Product> getProduct(
    @PathVariable Long id) {

    Product product = service.findById(id);

    if (product == null) {
        return ResponseEntity.notFound().build();
        // Returns 404 status
    }

    return ResponseEntity.ok(product);
    // Returns 200 with product data
}

Setting Response Status

@PostMapping("/users")
@ResponseStatus(HttpStatus.CREATED) // 201
public User createUser(@RequestBody User user) {
    return service.save(user);
}

Common HTTP Status Codes

Code Meaning When to Use
200 OK Success!
201 Created New thing made
400 Bad Request User sent wrong data
404 Not Found Thing doesnโ€™t exist
500 Server Error Something broke

Handling Errors Gracefully

@RestController
public class ProductController {

    @GetMapping("/products/{id}")
    public ResponseEntity<Product> getProduct(
        @PathVariable Long id) {

        try {
            Product p = service.findById(id);
            return ResponseEntity.ok(p);
        } catch (NotFoundException e) {
            return ResponseEntity
                .status(HttpStatus.NOT_FOUND)
                .body(null);
        }
    }
}

๐ŸŽฏ The Complete Picture

@RestController
@RequestMapping("/api/orders")
public class OrderController {

    private final OrderService service;

    // Constructor injection
    public OrderController(OrderService service) {
        this.service = service;
    }

    // GET /api/orders
    @GetMapping
    public List<Order> getAllOrders() {
        return service.findAll();
    }

    // GET /api/orders/42
    @GetMapping("/{id}")
    public ResponseEntity<Order> getOrder(
        @PathVariable Long id) {

        Order order = service.findById(id);
        if (order == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(order);
    }

    // POST /api/orders
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Order createOrder(
        @RequestBody Order order) {
        return service.save(order);
    }

    // DELETE /api/orders/42
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteOrder(@PathVariable Long id) {
        service.delete(id);
    }
}

๐ŸŒŸ Remember This!

  1. DispatcherServlet = The traffic cop. Routes all requests.

  2. MVC = Model carries data, View shows it, Controller decides.

  3. Two Controllers: @Controller for pages, @RestController for APIs.

  4. Mapping Shortcuts: @GetMapping, @PostMapping, etc.

  5. Data Extraction: @PathVariable, @RequestParam, @RequestBody, @RequestHeader

  6. Responses: Return views, data, or ResponseEntity for full control.


๐Ÿš€ You Did It!

You now understand how Spring handles web requests from start to finish. Like a well-organized castle mail room, Springโ€™s web controllers:

  • Receive requests (letters arrive)
  • Route them properly (DispatcherServlet)
  • Process them (Controllers)
  • Return responses (send replies)

Go build something amazing! ๐ŸŽ‰

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.