Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

Spring MVC Controllers, Views, Models, Dispatcher Servlet: Tutorial, Examples, FAQs & Interview Tips

Spring MVC Architecture

Spring MVC is a web framework built on the Servlet API. It follows the Model-View-Controller pattern. The central component is the DispatcherServlet, which acts as a front controller - it receives all requests and delegates them to the appropriate handler (controller).

Request flow: Browser -> DispatcherServlet -> HandlerMapping -> Controller -> Service -> Model -> ViewResolver -> View (JSP/Thymeleaf) -> Response

Spring MVC Controller
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import javax.validation.Valid;

@Controller
@RequestMapping("/products")
public class ProductController {

    private final ProductService productService;

    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    // GET /products - List all products
    @GetMapping
    public String listProducts(Model model) {
        model.addAttribute("products", productService.findAll());
        model.addAttribute("title", "Product List");
        return "products/list"; // View name: templates/products/list.html
    }

    // GET /products/{id} - Show product detail
    @GetMapping("/{id}")
    public String showProduct(@PathVariable Long id, Model model) {
        Product product = productService.findById(id);
        model.addAttribute("product", product);
        return "products/detail";
    }

    // GET /products/new - Show create form
    @GetMapping("/new")
    public String showCreateForm(Model model) {
        model.addAttribute("product", new Product());
        return "products/form";
    }

    // POST /products - Create product
    @PostMapping
    public String createProduct(@Valid @ModelAttribute Product product,
                                BindingResult result) {
        if (result.hasErrors()) {
            return "products/form"; // Return to form with errors
        }
        productService.save(product);
        return "redirect:/products"; // Post-Redirect-Get pattern
    }

    // GET /products/{id}/edit - Show edit form
    @GetMapping("/{id}/edit")
    public String showEditForm(@PathVariable Long id, Model model) {
        model.addAttribute("product", productService.findById(id));
        return "products/form";
    }

    // POST /products/{id} - Update product
    @PostMapping("/{id}")
    public String updateProduct(@PathVariable Long id,
                                @Valid @ModelAttribute Product product,
                                BindingResult result) {
        if (result.hasErrors()) return "products/form";
        product.setId(id);
        productService.save(product);
        return "redirect:/products/" + id;
    }

    // POST /products/{id}/delete - Delete product
    @PostMapping("/{id}/delete")
    public String deleteProduct(@PathVariable Long id) {
        productService.deleteById(id);
        return "redirect:/products";
    }
}

Request Mapping Annotations

AnnotationHTTP MethodEquivalent
@RequestMappingAnyBase mapping
@GetMappingGET@RequestMapping(method=GET)
@PostMappingPOST@RequestMapping(method=POST)
@PutMappingPUT@RequestMapping(method=PUT)
@DeleteMappingDELETE@RequestMapping(method=DELETE)
@PatchMappingPATCH@RequestMapping(method=PATCH)
Thymeleaf Template Example
<!-- templates/products/list.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:text="${title}">Products</title>
</head>
<body>
    <h1 th:text="${title}">Product List</h1>

    <a th:href="@{/products/new}">Add New Product</a>

    <table>
        <thead>
            <tr><th>ID</th><th>Name</th><th>Price</th><th>Actions</th></tr>
        </thead>
        <tbody>
            <tr th:each="product : ${products}">
                <td th:text="${product.id}"></td>
                <td th:text="${product.name}"></td>
                <td th:text="${#numbers.formatCurrency(product.price)}"></td>
                <td>
                    <a th:href="@{/products/{id}(id=${product.id})}">View</a>
                    <a th:href="@{/products/{id}/edit(id=${product.id})}">Edit</a>
                    <form th:action="@{/products/{id}/delete(id=${product.id})}" method="post">
                        <button type="submit">Delete</button>
                    </form>
                </td>
            </tr>
        </tbody>
    </table>
</body>
</html>
@PathVariable, @RequestParam, @ModelAttribute
@Controller
public class BindingExamples {

    // @PathVariable: /users/42
    @GetMapping("/users/{id}")
    public String getUser(@PathVariable Long id, Model model) {
        model.addAttribute("user", userService.findById(id));
        return "user/detail";
    }

    // Multiple path variables: /orders/5/items/3
    @GetMapping("/orders/{orderId}/items/{itemId}")
    public String getOrderItem(@PathVariable Long orderId,
                               @PathVariable Long itemId, Model model) {
        model.addAttribute("item", orderService.getItem(orderId, itemId));
        return "order/item";
    }

    // @RequestParam: /search?q=java&page=1&size=10
    @GetMapping("/search")
    public String search(@RequestParam String q,
                         @RequestParam(defaultValue = "1") int page,
                         @RequestParam(defaultValue = "10") int size,
                         @RequestParam(required = false) String category,
                         Model model) {
        model.addAttribute("results", searchService.search(q, page, size, category));
        return "search/results";
    }

    // @ModelAttribute: binds form fields to object
    @PostMapping("/register")
    public String register(@ModelAttribute @Valid UserForm form,
                           BindingResult errors, Model model) {
        if (errors.hasErrors()) {
            return "auth/register";
        }
        userService.register(form);
        return "redirect:/login?registered=true";
    }
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.