Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Spring MVC

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.