Spring MVC tutorial: Hướng dẫn xây ứng dụng web với Spring MVC

Khi nhắc đến hệ sinh thái Java, Spring MVC luôn là lựa chọn hàng đầu. Nhưng làm thế nào để áp dụng nó một cách hiệu quả vào công việc? Bài viết Spring MVC tutorial sau không chỉ là một bài hướng dẫn thông thường mà nó là một hành trình thực chiến, nơi bạn sẽ học cách tư duy như một nhà phát triển thực thụ, xây dựng một ứng dụng web từ con số 0 và trang bị những kỹ năng sẵn sàng cho các dự án trong tương lai. 

Đọc bài viết Spring MVC tutorial này để hiểu thêm về:

  • Những kiến thức tổng quan về Spring MVC
  • Cách xây dựng ứng dụng với Spring MVC
  • Các hướng nâng cấp ứng dụng Spring MVC lên “tầm cao mới”

Kiến thức tổng quan về Spring MVC

Để xây dựng thành công một ứng dụng web với Spring MVC, việc đầu tiên là nắm vững các khái niệm nền tảng:

Mô hình MVC (Model – View – Controller)

Về cốt lõi, Spring MVC tuân thủ nghiêm ngặt mô hình kiến trúc Model – View – Controller, giúp tổ chức code một cách rõ ràng và hiệu quả:

  • Model: Là nơi chứa dữ liệu của ứng dụng. Đây thường là các đối tượng Java đơn giản (POJO) đại diện cho các thực thể như User, Product, hay Order.
  • View: Chịu trách nhiệm hiển thị dữ liệu cho người dùng. Trong các dự án hiện đại, View thường là các file template như Thymeleaf hoặc JSP.
  • Controller: Đóng vai trò là “bộ não” trung tâm, tiếp nhận các yêu cầu từ người dùng, tương tác với Model để xử lý logic và cuối cùng quyết định View nào sẽ được trả về.

Luồng hoạt động của một yêu cầu trong Spring MVC (Request Flow)

Luồng hoạt động của một yêu cầu trong Spring MVC diễn ra một cách tuần tự và có tổ chức. Mọi thứ bắt đầu khi client gửi yêu cầu, yêu cầu này sẽ được DispatcherServlet (bộ điều phối trung tâm) tiếp nhận. DispatcherServlet sau đó sẽ tìm đến Controller tương ứng để xử lý. Controller làm việc với dữ liệu (Model), sau đó trả kết quả về lại cho DispatcherServlet, và cuối cùng View sẽ được render để gửi phản hồi (Response) về cho client.

Các Annotation (chú thích) quan trọng nhất:

Để biến luồng hoạt động trên thành code, Spring cung cấp các Annotation (chú thích) cực kỳ mạnh mẽ và tiện lợi. Đây là những công cụ không thể thiếu:

  • @Controller: Đánh dấu một class là một Controller.
  • @RequestMapping, @GetMapping, @PostMapping: Dùng để ánh xạ (map) một URL cụ thể với một phương thức xử lý trong Controller.
  • @RequestParam: Giúp bạn dễ dàng lấy các tham số từ URL (ví dụ: ?name=John).
  • @ModelAttribute: Dùng để liên kết dữ liệu được gửi lên từ một form HTML với một đối tượng Model của bạn.

Những khái niệm trên chính là những viên gạch đầu tiên và quan trọng nhất để bạn xây dựng nên một ứng dụng web hoàn chỉnh. Để tìm hiểu sâu hơn về cách các thành phần này kết hợp với nhau và xem hướng dẫn chi tiết từng bước trong một dự án thực tế, mời bạn đọc tiếp phần hướng dẫn thực hành dưới đây.

Đọc chi tiết: Spring MVC là gì: Hướng dẫn xây dựng ứng dụng với Spring MVC

Spring MVC tutorial: Thực hành xây dựng ứng dụng với Spring MVC

Trong phần này, chúng ta sẽ tạo ra một ứng dụng quản lý công việc (To-Do List) đơn giản. Qua Spring MVC tutorial sau đây, bạn sẽ học được cách hiển thị dữ liệu, xử lý người dùng nhập liệu qua form và cập nhật giao diện một cách linh hoạt. Cụ thể:

  • Hiểu và áp dụng mô hình MVC: Phân tách rõ ràng luồng dữ liệu (Model), giao diện (View), và logic xử lý (Controller).
  • Tạo Controller để xử lý request: Sử dụng các annotation @Controller, @GetMapping, và @PostMapping để điều hướng các yêu cầu của người dùng.
  • Xây dựng giao diện động với Thymeleaf: Truyền dữ liệu từ Controller ra View (Model.addAttribute) và hiển thị chúng một cách linh hoạt (th:text, th:each).
  • Xử lý Form một cách chuyên nghiệp: Nắm bắt dữ liệu người dùng nhập vào bằng @ModelAttribute và thực hiện kỹ thuật Post-Redirect-Get (PRG) để tạo ra trải nghiệm người dùng tốt hơn và tránh lỗi.

Phần 1: Tạo trang chủ “Hello, World!”

Bước 1: Tạo Controller đầu tiên (HomeController.java)

Mục đích: Tạo ra một “bộ não” có khả năng lắng nghe và phản hồi lại các yêu cầu từ người dùng khi họ truy cập vào trang chủ của ứng dụng. Đây là thành phần Controller trong mô hình MVC.

Cách làm:

  1. Tạo một class Java mới tên là HomeController.
  2. Sử dụng annotation @Controller để báo cho Spring biết rằng đây là một bean đặc biệt, chịu trách nhiệm xử lý các request web.
  3. Bên trong class, tạo một phương thức showHomePage(). Phương thức này sẽ được gọi khi có người truy cập vào trang chủ.
  4. Sử dụng annotation @GetMapping("/") để ánh xạ (map) phương thức này với URL gốc (/) của trang web thông qua phương thức GET.
  5. Phương thức sẽ trả về một String. String này chính là tên logic của View mà chúng ta muốn hiển thị.

Ví dụ code (HomeController.java):

package com.example.todomvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String showHomePage() {
        // Trả về tên của file view (không bao gồm đuôi .html)
        return "home";
    }
}

Output: 

Bản thân đoạn code này khi chạy sẽ không tạo ra bất kỳ giao diện có thể nhìn thấy nào. “Output” của nó là một tín hiệu nội bộ bên trong Spring MVC. Khi phương thức showHomePage() được thực thi, nó trả về chuỗi “home”. Đây là tên logic của View.

Giải thích: 

  • Khi người dùng truy cập http://localhost:8080/, DispatcherServlet của Spring sẽ tìm kiếm xem có phương thức nào được đăng ký để xử lý URL / với phương thức GET hay không. 
  • Nhờ @GetMapping("/"), nó sẽ tìm thấy phương thức showHomePage(). Phương thức này thực thi và trả về chuỗi “home”. Spring MVC sẽ hiểu rằng nó cần phải tìm một template tên là home để hiển thị cho người dùng.

    Bước 2: Hiển thị danh sách công việc và Form thêm mới

    Mục đích: Tạo ra giao diện người dùng (file HTML) mà người dùng sẽ nhìn thấy. Đây là thành phần View trong mô hình MVC.

    Cách làm: Spring Boot với Thymeleaf được cấu hình mặc định để tìm các file template trong thư mục src/main/resources/templates.

    • Trong project của bạn, điều hướng đến thư mục src/main/resources.
    • Tạo một file HTML mới và đặt tên là home.html (trùng với tên logic mà Controller đã trả về).
    • Thêm một vài thẻ HTML cơ bản vào file này.

    Ví dụ code (home.html):

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Ứng dụng To-Do</title>
    </head>
    <body>
        <h1>Chào mừng đến với ứng dụng quản lý công việc!</h1>
    </body>
    </html>

    Giải thích: Khi Controller trả về tên view là “home”, ViewResolver của Spring sẽ tự động tìm kiếm file home.html trong thư mục templates. Sau đó, nó sẽ render file HTML này và gửi về cho trình duyệt của người dùng.

    Bước 3: Truyền dữ liệu từ Controller sang View

    Mục đích: Làm cho trang web trở nên động bằng cách gửi dữ liệu từ backend và hiển thị nó trên giao diện. Đây là bước kết nối Controller với View thông qua Model.

    Cách làm:

    1. Sửa lại phương thức showHomePage() trong HomeController. Thêm một tham số có kiểu Model vào phương thức. Spring sẽ tự động cung cấp một đối tượng Model cho chúng ta.
    2. Sử dụng phương thức model.addAttribute("key", "value") để thêm một thuộc tính vào model. “key” là tên để chúng ta gọi ở View, “value” là giá trị chúng ta muốn truyền đi.
    3. Mở file home.html và sử dụng cú pháp của Thymeleaf để truy cập và hiển thị giá trị đã được truyền qua.

    Code: HomeController.java

    package com.example.todomvc.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model; // Thêm import
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class HomeController {
    
        @GetMapping("/")
        public String showHomePage(Model model) { // Thêm tham số Model
            // Thêm một thuộc tính vào model để gửi sang View
            model.addAttribute("welcomeMessage", "Đây là thông điệp từ Controller!");
            return "home";
        }
    }

    Home.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Ứng dụng To-Do</title>
    </head>
    <body>
        <h1>Chào mừng đến với ứng dụng quản lý công việc!</h1>
        <p th:text="${welcomeMessage}"></p>
    </body>
    </html>

    Output và giải thích: 

    • Khi bạn chạy lại ứng dụng, trang chủ bây giờ sẽ hiển thị thêm dòng chữ: “Đây là thông điệp từ Controller!”. 
    • Thymeleaf nhìn thấy th:text="${welcomeMessage}" và hiểu rằng nó cần tìm một thuộc tính tên là welcomeMessage trong đối tượng Model mà Controller đã gửi. Nó sẽ lấy giá trị của thuộc tính đó và đặt vào bên trong thẻ <p>.

    Bước 4: Chạy ứng dụng và xem kết quả

    Mục đích: Kiểm tra thành quả của các bước trên và đảm bảo ứng dụng chạy đúng như mong đợi.

    Cách làm:

    • Trong IDE của bạn (IntelliJ, Eclipse, VSCode), tìm đến class chính của ứng dụng (class có annotation @SpringBootApplication).
    • Nhấn chuột phải vào class đó và chọn “Run” hoặc “Debug”.
    • IDE sẽ build và khởi chạy server Tomcat nhúng. Chờ đến khi console log báo “Tomcat started on port(s): 8080”.

    Output và giải thích: Mở trình duyệt web (Chrome, Firefox,…) và truy cập vào địa chỉ: http://localhost:8080. Bạn sẽ thấy trang web của mình hiện ra với đầy đủ tiêu đề và dòng thông điệp được truyền từ Controller.

    Phần 2: Xử lý Form – Thêm công việc mới

    Bây giờ, chúng ta sẽ nâng cấp ứng dụng để có thể thêm các công việc mới vào danh sách thông qua một form HTML.

    Bước 1: Tạo Model Object (Todo.java)

    Mục đích: Định nghĩa cấu trúc dữ liệu cho một “công việc” (Todo). Thay vì dùng các chuỗi (String) rời rạc, chúng ta tạo một đối tượng cụ thể để đóng gói thông tin. Đây là thành phần Model thực sự trong mô hình MVC.

    Cách làm: Tạo một class Java POJO (Plain Old Java Object) với các trường dữ liệu cần thiết, cùng với constructor, getter và setter.

    Ví dụ code (Todo.java):

    package com.example.todomvc.model;
    
    public class Todo {
        private long id;
        private String title;
        private boolean completed;
    
        // Constructors
        public Todo() {}
    
        public Todo(long id, String title, boolean completed) {
            this.id = id;
            this.title = title;
            this.completed = completed;
        }
    
        // Getters and Setters
        public long getId() { return id; }
        public void setId(long id) { this.id = id; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public boolean isCompleted() { return completed; }
        public void setCompleted(boolean completed) { this.completed = completed; }
    }

    Giải thích: Class Todo này là một bản thiết kế cho dữ liệu công việc. Mỗi đối tượng Todo sẽ đại diện cho một công việc trong danh sách của chúng ta. Spring sẽ sử dụng class này để tự động tạo đối tượng từ dữ liệu của form.

    Bước 2: Hiển thị danh sách công việc và Form thêm mới

    Mục đích: Cập nhật Controller để quản lý một danh sách công việc và truyền danh sách đó ra View. Đồng thời, cập nhật View để hiển thị danh sách này và một form cho phép người dùng nhập công việc mới.

    Cách làm:

    Trong HomeController: Tạo một List<Todo> để lưu trữ các công việc (chúng ta sẽ dùng một danh sách trong bộ nhớ để đơn giản hóa, thay vì dùng database). Truyền danh sách này và một đối tượng Todo rỗng (dùng cho form) vào model.

    Trong home.html:

    1. Sử dụng vòng lặp th:each của Thymeleaf để duyệt qua danh sách công việc và hiển thị chúng.
    2. Tạo một thẻ <form> với các thuộc tính của Thymeleaf (th:action, th:object) để liên kết form với đối tượng và action trong Controller.
    3. Sử dụng th:field cho thẻ <input> để liên kết nó với một thuộc tính cụ thể của đối tượng.

    Ví dụ code: HomeController.java:

    package com.example.todomvc.controller;
    
    import com.example.todomvc.model.Todo; // Thêm import
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    import java.util.ArrayList; // Thêm import
    import java.util.List;      // Thêm import
    
    @Controller
    public class HomeController {
    
        // Dùng một danh sách đơn giản trong bộ nhớ để làm CSDL giả
        private final List<Todo> todoList = new ArrayList<>();
    
        public HomeController() {
            // Thêm một vài dữ liệu mẫu
            todoList.add(new Todo(1, "Học Spring MVC", true));
            todoList.add(new Todo(2, "Xây dựng ứng dụng To-Do", false));
        }
    
        @GetMapping("/")
        public String showHomePage(Model model) {
            // Truyền danh sách công việc và một đối tượng rỗng cho form
            model.addAttribute("todos", todoList);
            model.addAttribute("newTodo", new Todo()); // Đối tượng để binding với form
            return "home";
        }
    }

    Home.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Ứng dụng To-Do</title>
    </head>
    <body>
        <h1>Danh sách công việc</h1>
    
        <ul>
            <li th:each="todo : ${todos}" th:text="${todo.title}">
                Nội dung công việc
            </li>
        </ul>
    
        <hr/>
    
        <h2>Thêm công việc mới</h2>
        <form action="#" th:action="@{/add-todo}" th:object="${newTodo}" method="post">
            <input type="text" th:field="*{title}" placeholder="Nhập tiêu đề công việc"/>
            <button type="submit">Thêm</button>
        </form>
    
    </body>
    </html>

    Giải thích:

    • th:each="todo : ${todos}": Thymeleaf sẽ lặp qua từng đối tượng todo trong danh sách todos được truyền từ Controller. Với mỗi todo, nó sẽ tạo ra một thẻ <li>.
    • th:text="${todo.title}": Hiển thị giá trị của thuộc tính title của đối tượng todo hiện tại.
    • th:action="@{/add-todo}": Chỉ định rằng khi form được submit, nó sẽ gửi yêu cầu POST đến URL /add-todo.
    • th:object="${newTodo}": Liên kết (binding) toàn bộ form này với đối tượng newTodo trong model.
    • th:field="*{title}": Liên kết thẻ <input> này với thuộc tính title của đối tượng đang được liên kết (newTodo). Dấu * là cú pháp tắt cho newTodo.title.

    Bước 3: Xử lý việc gửi Form (Submit)

    Mục đích: Tạo một phương thức trong Controller để nhận dữ liệu khi người dùng nhấn nút “Thêm” trên form, xử lý dữ liệu đó (thêm vào danh sách) và cập nhật lại giao diện.

    Cách làm:

    1. Tạo một phương thức mới trong HomeController.
    2. Sử dụng @PostMapping("/add-todo") để ánh xạ phương thức này với action của form.
    3. Sử dụng @ModelAttribute trên tham số của phương thức. Spring sẽ tự động lấy dữ liệu từ form và tạo ra một đối tượng Todo cho chúng ta.
    4. Thêm đối tượng Todo mới vào todoList.
    5. Trả về redirect:/. Đây là một kỹ thuật quan trọng, yêu cầu trình duyệt thực hiện một request GET mới đến trang chủ, giúp tải lại danh sách đã được cập nhật và tránh lỗi gửi lại form khi người dùng nhấn F5.

    Ví dụ code (HomeController.java – thêm phương thức mới):

    // ... (bên trong class HomeController)
    
    import org.springframework.web.bind.annotation.ModelAttribute; // Thêm import
    import org.springframework.web.bind.annotation.PostMapping;    // Thêm import
    
    // ... (phương thức showHomePage và constructor vẫn giữ nguyên)
    
    @PostMapping("/add-todo")
    public String addTodo(@ModelAttribute Todo newTodo) {
        // Gán ID tạm thời (trong ứng dụng thực tế sẽ do CSDL quản lý)
        newTodo.setId(System.currentTimeMillis());
        newTodo.setCompleted(false);
    
        // Thêm công việc mới vào danh sách
        this.todoList.add(newTodo);
    
        // Chuyển hướng về trang chủ để hiển thị danh sách đã cập nhật
        return "redirect:/";
    }

    Giải thích:

    • @PostMapping("/add-todo"): Chỉ lắng nghe các request dùng phương thức POST đến URL /add-todo.
    • @ModelAttribute Todo newTodo: Đây là “phép màu” của Spring. Nó nhìn vào các name của input trong form, so khớp chúng với các thuộc tính của class Todo, và tự động tạo một đối tượng newTodo với các giá trị tương ứng.
    • return "redirect:/": Thay vì trả về một tên view, chúng ta trả về một lệnh chuyển hướng. Trình duyệt sẽ nhận lệnh này và tự động gửi một request mới đến /. Request này sẽ được showHomePage() xử lý, lấy ra danh sách todoList (lúc này đã có phần tử mới) và hiển thị lại trang chủ.

    Bước 4: Kiểm tra lại

    Mục đích: Chạy lại ứng dụng và kiểm tra toàn bộ luồng chức năng thêm mới có hoạt động đúng không.

    Cách làm:

    • Chạy lại ứng dụng của bạn từ IDE.
    • Mở trình duyệt tại http://localhost:8080.

    Output và giải thích: 

    • Bạn sẽ thấy trang chủ với danh sách 2 công việc mẫu. Hãy thử nhập một tiêu đề công việc mới vào ô input (ví dụ: “Hoàn thành bài hướng dẫn”) và nhấn nút “Thêm”. 
    • Ngay lập tức, trang sẽ được tải lại, và công việc bạn vừa thêm sẽ xuất hiện ở cuối danh sách. 
    • Điều này xác nhận rằng toàn bộ luồng: Hiển thị Form -> Người dùng nhập liệu -> Submit -> Controller xử lý -> Thêm vào danh sách -> Redirect -> Hiển thị lại danh sách mới đã thành công!

    Ứng dụng To-Do List vừa làm chỉ là bước khởi đầu. Trong một dự án thực tế, nó cần được hoàn thiện hơn. Giờ là lúc khám phá xem chúng ta có thể nâng cấp ứng dụng này lên những tầm cao mới nào.

    Hướng “nâng cấp” ứng dụng

    Dưới đây là những bước phát triển quan trọng mà bạn nên tìm hiểu tiếp theo:

    Validation – Kiểm tra dữ liệu đầu vào

    • Vấn đề: Hiện tại, người dùng có thể submit một form với tiêu đề công việc trống rỗng. Điều này sẽ tạo ra dữ liệu không mong muốn trong hệ thống.
    • Giải pháp: Sử dụng Spring Boot Validation. Bằng cách thêm các annotation như @NotEmpty hay @Size vào các trường của Model class (Todo.java) và dùng @Valid trong Controller, bạn có thể tự động kiểm tra dữ liệu trước khi xử lý. Nếu dữ liệu không hợp lệ, bạn có thể hiển thị thông báo lỗi thân thiện cho người dùng ngay trên form.

    Từ khóa để tìm hiểu: Spring Boot Validation, Hibernate Validator, @Valid, @NotEmpty, BindingResult.

    Kết nối Cơ sở dữ liệu với Spring Data JPA

    • Vấn đề: Danh sách công việc của chúng ta đang được lưu trong một ArrayList trong bộ nhớ. Mỗi khi bạn khởi động lại ứng dụng, toàn bộ dữ liệu sẽ bị mất.
    • Giải pháp: Sử dụng Spring Data JPAHibernate để kết nối ứng dụng với một cơ sở dữ liệu thực sự (như H2, MySQL, PostgreSQL). Điều này giúp dữ liệu được lưu trữ lâu dài. Spring Data JPA cung cấp các interface như JpaRepository giúp bạn thực hiện các thao tác CRUD (Create, Read, Update, Delete) với CSDL mà không cần viết các câu lệnh SQL phức tạp.

    Từ khóa để tìm hiểu: Spring Data JPA, @Entity, JpaRepository, Hibernate, JDBC DataSource configuration.

    Xây dựng REST API

    • Vấn đề: Ứng dụng của chúng ta hiện tại chỉ phục vụ giao diện web (server-rendered HTML). Nếu bạn muốn một ứng dụng di động (mobile app) hoặc một trang web dùng JavaScript (React, Angular) có thể tương tác với dữ liệu công việc thì sao?
    • Giải pháp: Xây dựng các REST API. Thay vì trả về tên của một View, Controller sẽ trả về dữ liệu dưới dạng JSON. Bạn sẽ sử dụng annotation @RestController thay cho @Controller để Spring tự động chuyển đổi các đối tượng Java thành JSON.

    Từ khóa để tìm hiểu: @RestController, @ResponseBody, ResponseEntity, JSON, Spring Boot REST API.

    Bảo mật với Spring Security

    • Vấn đề: Bất kỳ ai cũng có thể truy cập và thêm công việc vào danh sách. Trong thực tế, bạn sẽ muốn mỗi người dùng chỉ có thể xem và quản lý danh sách công việc của riêng mình.
    • Giải pháp: Tích hợp Spring Security vào dự án. Đây là một framework cực kỳ mạnh mẽ cho phép bạn thêm các tính năng như đăng nhập, đăng ký, phân quyền người dùng. Bạn có thể cấu hình để chỉ những người dùng đã đăng nhập (authenticated) mới có thể truy cập các trang nhất định, và chỉ những người có quyền (authorized) mới được thực hiện một số hành động.

    Từ khóa để tìm hiểu: Spring Security, Authentication, Authorization, SecurityFilterChain, PasswordEncoder.

    Các câu hỏi thường gặp về Spring MVC tutorial

    Sự khác biệt giữa thư mục templatesstatic là gì?

    Cả hai đều nằm trong src/main/resources, nhưng có mục đích hoàn toàn khác nhau:

    • src/main/resources/templates: Dành cho các file động. Các file trong này (như home.html của chúng ta) sẽ được một template engine (Thymeleaf) xử lý ở phía server trước khi gửi về cho trình duyệt. Server có thể chèn dữ liệu vào các file này.
    • src/main/resources/static: Dành cho các tài nguyên tĩnh. Các file trong này như CSS, JavaScript, hình ảnh, fonts… sẽ được server gửi trực tiếp về cho trình duyệt mà không qua bất kỳ xử lý nào. Ví dụ, nếu bạn tạo file style.css trong này, bạn có thể link nó trong HTML bằng thẻ <link rel="stylesheet" href="/style.css">.

    Sự khác biệt giữa @Controller@RestController là gì?

    • @Controller: Được sử dụng để tạo các web controller truyền thống trong Spring MVC. Các phương thức trong @Controller thường trả về một String là tên của một View (template) để hiển thị giao diện người dùng (HTML).
    • @RestController: Là một annotation kết hợp giữa @Controller@ResponseBody. Nó được sử dụng chuyên để xây dựng RESTful API. Các phương thức trong @RestController thường trả về trực tiếp dữ liệu (ví dụ: đối tượng Java), và Spring sẽ tự động chuyển đổi nó thành định dạng JSON để các ứng dụng khác (như mobile app, trang web React/Angular) có thể sử dụng.

    Trong bài hướng dẫn này, chúng ta xây dựng ứng dụng web trả về HTML nên đã dùng @Controller.

    @ModelAttribute hoạt động như thế nào mà có thể tự tạo đối tượng Todo?

    @ModelAttribute là một annotation cực kỳ mạnh mẽ giúp đơn giản hóa việc liên kết dữ liệu (data binding). Khi một form được submit, các dữ liệu của nó được gửi đi dưới dạng các cặp key-value (ví dụ: title=Mua sữa).

    @ModelAttribute sẽ:

    1. Tạo một instance mới của đối tượng được chỉ định (ví dụ: new Todo()).
    2. Nhìn vào các key trong dữ liệu request (title).
    3. Tìm phương thức setter tương ứng trong đối tượng (setTitle(...)).
    4. Gọi phương thức setter đó với value tương ứng ("Mua sữa").

    Nó giúp chúng ta không phải làm các công việc thủ công và nhàm chán như:

    String title = request.getParameter("title"); todo.setTitle(title);

    Tổng kết Spring MVC tutorial

    Với Spring MVC tutorial trên, bạn không chỉ biến những khái niệm lý thuyết thành một sản phẩm chạy được, mà còn nắm được những nguyên tắc hoạt động cốt lõi nhất của Spring MVC. Đây là một nền tảng cực kỳ vững chắc để bạn tiếp tục chinh phục những công nghệ phức tạp hơn trong hệ sinh thái Spring.

    TÁC GIẢ
    Tien Tran
    Tien Tran

    iOS Developer

    Có 4 năm kinh nghiệm trong lĩnh vực phát triển ứng dụng mobile, được chứng minh qua lịch sử làm việc ở các công ty lớn (VCCorp, KiotViet, Vega Fintech). Với đam mê tìm hiểu, nghiên cứu những kiến thức chuyên môn cần có của một lập trình viên mobile hiện nay như Swift, Objective C, Flutter, Kotlin,... Tiến mong muốn chia sẻ kinh nghiệm làm việc và truyền cảm hứng cho mọi người muốn theo đuổi con đường trở thành một nhà phát triển ứng dụng di động chuyên nghiệp trong tương lai.