Tìm hiểu về Spring Boot MVC
Đăng lúc: 10:01 AM - 15/03/2025 bởi Charles Chung - 367Trong bài này tôi sẽ giới thiệu về các mô hình MVC, SpringBoot MVC, cách tổ chức project SpringBoot MVC và các thành phần bên trong.

1. Giới thiệu về mô hình MVC
Model–View–Controller (thường được gọi là MVC) là một mẫu thiết kế phần mềm được sử dụng phổ biến để phát triển các ứng dụng web. Nó phân chia logic thành ba thành phần có liên quan với nhau. Ba thành phần là Model, View và Controller.
- Model là thành phần trung tâm của mẫu. Đây là cấu trúc dữ liệu động của ứng dụng, độc lập với giao diện người dùng. Model quản lý trực tiếp dữ liệu, logic và quy tắc nghiệp của ứng dụng.
- View là thành phần biểu diễn và trình bày thông tin cho người dùng cuối, ví dụ bảng biểu, bài viết, biều đồ, biểu mẫu nhập liệu...
- Controller là thành phần điều khiển, nhận yêu cầu từ người dùng và chuyển đổi thành lệnh cho model hoặc view để nhận phản hồi cho người dùng.
Tương tác giữa 3 thành phần với nhau
- Model chịu trách nhiệm quản lý dữ liệu của ứng dụng. Nó nhận dữ liệu đầu vào của người dùng từ Controller.
- View trình bày dữ liệu của Model theo một định dạng cụ thể.
- Controller phản hồi dữ liệu đầu vào của người dùng và thực hiện tương tác với các đối tượng dữ liệu Model. Hơn nữa, nó nhận dữ liệu đầu vào, tùy chọn xác thực dữ liệu đó và sau đó chuyển dữ liệu đầu vào cho Model.
2. Tại sao sử dụng MVC
- Phân tách rõ ràng giữa các thành phần UI, Business Logic, Model/Data.
- Dễ sửa đổi do sự phân tách trách nhiệm và nó làm tăng khả năng mở rộng của phần mềm.
- Phát triển đồng thời các thành phần riêng biệt theo lĩnh vực chuyên môn của từng người.
3. Giới thiệu về SpringBoot MVC
SpringBoot phát triển dựa trên Spring MVC do đó nó vẫn tuân theo mô hình MVC, tuy nhiên việc cấu hình mô hình MVC trong SpingBoot sẽ trở lên đơn giản hơn trong Spring MVC. Ngoài ra cấu trúc source code của Spring Boot còn được dựa trên hai mô hình, mô hình 3 lớp.
- Presentation layer: tầng này tương tác với người dùng, bằng View, Controller (trong MVC) hoặc API (nếu có).
- Business logic layer: Chứa toàn bộ logic của chương trình, các đa số code nằm ở đây
- Data access layer: Tương tác với database, trả về kết quả cho tầng business logic
Trong Spring Boot, thì có một số thành phần đại diện cho từng lớp:
- Service: chứa các business logic code
- Repository: đại diện cho tầng data access
Kết hợp hai mô hình lại, chúng ta có được ứng dụng Spring Boot hoàn chỉnh, gồm các thành phần sau:
- Controller: trả về View (có chứa data sẵn, dạng trang HTML), hoặc Model thể hiện dưới dạng API cho View (View viết riêng bằng React, Vue, hoặc Angular).
- Service: chứa các code tính toán, xử lý. Khi Controller yêu cầu, thì Service tương ứng sẽ tiếp nhận và cho ra dữ liệu trả cho Controller (trả về Model). Controller sẽ gửi về View như trên.
- Repository: Service còn có thể tương tác với service khác, hoặc dùng Repository để gọi DB. Repository là thằng trực tiếp tương tác, đọc ghi dữ liệu trong DB và trả cho service.
Luồng xử lý request trong SpringBoot
4. Các Annotation Mapping trong SpringBoot MVC
Trong SpringBoot sẽ sử dụng các Annotation để nhận diện các Controller và Action được thực thi. Một số Annotation gồm:
- @Controller: nhận diện controller
- @RequestMapping: nhận diện hành động được thực thi (GET/POST/PUT/DELETE)
- @GetMapping: nhận diện hành động thực thì với request GET
- @PostMapping: nhận diện hành động thực thì với request POST
- @PutMapping: nhận diện hành động được thực thi với request PUT
- @DeleteMapping: nhận diện hành động được thực thi với request DELETE
5. Tạo ứng dụng SpringBoot MVC
Trong ví dụ này chúng ta sẽ tạo ứng dụng SpringBoot hoàn chỉnh với các thành phần:
- Entities: chứa các lớp thực thể map với cấu trúc các table trong database
- Models: chứa các lớp model map với entities phục vụ cho view
- View (thymeleaf): trang html trong thư mục templates hiển thị dữ liệu gửi từ controllers
- Controllers: chứa các lớp controller điều khiển luồng trong ứng dụng MVC
- Services: chứa các lớp nghiệp vụ gọi từ repositories
- Repositories : chứa các lớp truy xuất dữ liệu trong db
- Others: Security, Config,…
Bước 1: Tạo project SpringBoot session2example1 với các dependencty xem chi tiết bài 1
Bước 2: Tạo các package, class, view như cấu trúc bên dưới
Bước 3: Code lớp Student (biểu diễn thực thể sinh viên)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package com.bkap.entities; public class Student { private String id; private String name; private boolean gender; private int age; public Student() { } public Student(String id, String name, boolean gender, int age) { super(); this.id = id; this.name = name; this.gender = gender; this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isGender() { return gender; } public void setGender(boolean gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } |
Bước 4: Code lớp StudentModel (Biểu diễn thông tin sinh viên hiển thị trên view)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.bkap.models; import com.bkap.entities.Student; public class StudentModel { private String id; private String name; private String gender; public StudentModel(Student st) { this.id = st.getId(); this.name = st.getName(); this.gender = st.isGender() ? "Nam" : "Nữ"; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } } |
Bước 5: Code lớp StudentService (biểu diễn các nghiệp vụ sinh viên)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.bkap.services; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.springframework.stereotype.Service; import com.bkap.entities.Student; import com.bkap.models.StudentModel; @Service public class StudentService { /* * Sử dụng @Autowired để khởi tạo repository Tuy nhiên bài này chúng ta không * làm việc với db nên không cần dùng repository */ private List<Student> students = new ArrayList<>(); public StudentService() { students.add(new Student("S1", "Nguyễn Văn Cảnh", true, 20)); students.add(new Student("S2", "Nguyễn Văn Tuấn", true, 22)); students.add(new Student("S3", "Nguyễn Thị Nhung", false, 21)); students.add(new Student("S4", "Trần Bách Thảo", false, 20)); students.add(new Student("S5", "Lê Sỹ Diện", true, 20)); } public List<StudentModel> getStudentList() { return students.stream().map(StudentModel::new).collect(Collectors.toList()); } } |
Bước 6: Code lớp StudentController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.bkap.controllers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import com.bkap.services.StudentService; @Controller public class StudentController { @Autowired StudentService studentService; @GetMapping("/") public String home(Model model) { model.addAttribute("msg", "TRANG CHỦ"); return "index"; } @GetMapping("student") public String liststudent(Model model) { model.addAttribute("students", studentService.getStudentList()); return "student"; } } |
Bước 7: Code view index.html
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Spring Boot MVC</title> </head> <body> <h1 th:text="${msg}"></h1> <a href="#" th:href="@{/student}">Danh sách sinh viên</a> </body> </html> |
- View student.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Danh sách sinh viên</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" /> </head> <body> <div class="container"> <h1 class="text-center">Danh sách sinh viên</h1> <table class="table table-bordered"> <tr> <th>Id</th> <th>Name</th> <th>Gender</th> <th></th> </tr> <tr th:each="st : ${students}"> <td th:text="*{st.id}">...</td> <td th:text="*{st.name}">...</td> <td>[[*{st.gender}]]</td> <td> <a th:href="@{student/detail/{id}(id=${st.id})}">Chi tiết</a> | <a th:href="@{student/edit/{id}(id=${st.id})}">Sửa</a> | <a th:href="@{student/delete/{id}(id=${st.id})}">Xóa</a> </td> </tr> </table> </div> </body> </html> |
Bước 8: Chạy ứng dụng và xem kết quả
Source code download tại đây
6. Video demo (quay trong buổi dạy lớp C2308G)
thay lời cảm ơn!
Các bài cũ hơn
- Hướng dẫn cài đặt môi trường phát triển ứng dụng web với Spring Boot 3 sử dụng Eclipse trên Windows (11:27 AM - 13/03/2025)
- Review đồ án kỳ 4 - Flutter Mobile App lớp C2303LM Bách Khoa Aptech (02:40 PM - 12/03/2025)
- Review đồ án SEM IV-App Đọc truyện online với Flutter Group3-C2110I2 Bách Khoa Aptech (09:53 AM - 20/10/2024)
- Review đồ án SEM IV-App E-commerce-Book Store với Flutter Group1-C2110I2 Bách Khoa Aptech (05:09 PM - 18/10/2024)
- Review đồ án SEM IV-App E-commerce với Flutter lớp C2110I2 Bách Khoa Aptech (09:03 AM - 17/10/2024)