hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Cấu trúc dữ liệu và giải thuật
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
      • NodeJS
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
      • MongoDB
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
      • Spring Boot
    • Lập trình C#
      • Lập Trình C# Cơ Bản
      • ASP.NET Core MVC
    • Lập trình Python
    • Git và Github
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
    • Mạng và truyền thông
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Spring Boot
Spring Boot bài 09: Binding biểu mẫu tạo và sửa khóa học
Java và Spring Boot – MVC và REST API

Spring Boot bài 09: Binding biểu mẫu tạo và sửa khóa học

  • 18-10-2026
  • Toanngo92
  • 0 Comments

Giáo trình Spring Boot MVC và REST API · Chương 5/12: Biểu mẫu, validation và điều hướng · Bài 09/28 · Biên soạn tháng 10/2026.

← Bài 08 · Mục lục 12 chương · Bài 10 →

Mục lục

  • Mục tiêu bài học
  • Form là hợp đồng đầu vào
  • Tên thuộc tính phải khớp
  • Chuyển DTO thành dữ liệu sửa
  • Kiểu dữ liệu và CSRF
  • Lỗi thường gặp và lưu ý
  • Ghi nhớ
  • Tài liệu đối chiếu

Mục tiêu bài học

Nối biểu mẫu HTML với CourseForm, phân biệt GET mở form và POST gửi dữ liệu, dùng lại form cho tạo và sửa.

Form là hợp đồng đầu vào

Biểu mẫu tạo khóa học cần tên, giá và mã danh mục. Ta dùng CourseForm chỉ chứa ba trường này, thay vì bind trực tiếp request vào entity Course. Entity còn có id và version do hệ thống quản lý; cho client tùy ý gán mọi thuộc tính có thể dẫn đến sửa dữ liệu ngoài ý định.

GET /admin/courses/new tạo form trống và cung cấp danh sách danh mục. GET /admin/courses/{id}/edit lấy DTO hiện có rồi chuyển thành CourseForm. Hai luồng dùng chung template courses/form, khác nhau ở dữ liệu ban đầu và action gửi đến. Đường dẫn quản trị yêu cầu tài khoản teacher.

<form th:action="${action}" th:object="${form}" method="post">
  <label>Tên <input th:field="*{title}" maxlength="120" required></label>
  <p th:errors="*{title}"></p>
  <label>Giá <input th:field="*{price}" type="number" min="0" step="0.01"></label>
  <p th:errors="*{price}"></p>
  <label>Danh mục
    <select th:field="*{categoryId}">
      <option value="">Chọn danh mục</option>
      <option th:each="c : ${categories}" th:value="${c.id}" th:text="${c.name}"></option>
    </select>
  </label>
  <button>Lưu</button>
</form>

Tên thuộc tính phải khớp

th:object chọn đối tượng form; th:field tạo name, id và value phù hợp cho từng thuộc tính. Khi POST, Spring lấy giá trị request và chuyển sang String, BigDecimal, Long bằng getter/setter của CourseForm. Tên categoryId trong select phải tương ứng thuộc tính của form, không phải categoryName hoặc tên cột database.

Danh mục hiển thị tên để người dùng chọn, nhưng gửi id để Service tìm bản ghi thực sự. Một người có thể sửa HTML và gửi id không tồn tại, nên việc danh sách select chỉ chứa dữ liệu hợp lệ không đủ đảm bảo đầu vào hợp lệ. Service vẫn kiểm tra danh mục.

Chuyển DTO thành dữ liệu sửa

Phương thức edit không đưa nguyên entity vào form. Nó lấy DTO, tạo CourseForm và gán từng trường được cho sửa. id cần sửa nằm trong URL, không lấy từ một thuộc tính id không kiểm soát trong body. Cách này làm rõ tài nguyên nào được chọn và thuộc tính nào người dùng được thay đổi.

Tệp trong mã nguồn mẫu: src/main/java/com/hocvietcode/academy/CourseWebController.java. Đoạn dưới được trích từ tệp này; xem bản tải về để có đủ import và phần còn lại.

@GetMapping("/admin/courses/{id}/edit") String edit(@PathVariable Long id,Model model){
    CourseDto dto=service.get(id);CourseForm form=new CourseForm();form.setTitle(dto.title());form.setPrice(dto.price());form.setCategoryId(dto.categoryId());
    model.addAttribute("form",form);model.addAttribute("action","/admin/courses/"+id);model.addAttribute("categories",service.categories());return "courses/form";
}

Kiểu dữ liệu và CSRF

Giá dùng BigDecimal để biểu diễn số thập phân, không dùng double cho giá tiền. Nếu nhập ký tự vào ô giá bằng cách gửi request thủ công, lỗi chuyển kiểu được đưa vào BindingResult. Bài sau xử lý tình huống đó mà không đánh mất dữ liệu người dùng vừa nhập.

Form POST dùng th:action để tích hợp với Spring và chèn CSRF token khi Security bật. Sau khi render, hãy kiểm tra có input ẩn _csrf. Không tự tạo một chuỗi token giả hoặc bỏ CSRF vì request bị 403. Lỗi binding là vấn đề dữ liệu; lỗi CSRF xảy ra ở tầng Security và thường ngăn request đi tới Controller.

Lỗi thường gặp và lưu ý

  • Không bind trực tiếp toàn bộ entity nếu client chỉ được sửa một số trường.
  • Nếu trả lại form sau lỗi, nhớ cung cấp lại categories và action để form vẫn hoạt động.

Ghi nhớ

GET chuẩn bị biểu mẫu, POST bind dữ liệu vào một đối tượng đầu vào giới hạn; Service kiểm tra nghiệp vụ và lưu thay đổi.

Tài liệu đối chiếu

  • ModelAttribute

← Bài 08 · Mục lục 12 chương · Bài 10 →

Bài viết liên quan:

Java và Spring Boot – MVC và REST API
Spring Boot bài 16: Upload và download tài liệu có giới hạn
Java và Spring Boot – MVC và REST API
Spring Boot bài 17: Spring Security: đăng nhập, mật khẩu và SecurityFilterChain
Java và Spring Boot – MVC và REST API
Spring Boot bài 18: Phân quyền teacher/student và bảo vệ endpoint
Java và Spring Boot – MVC và REST API
Spring Boot bài 19: CSRF, CORS và gọi API có session đúng cách
Java và Spring Boot – MVC và REST API
Spring Boot bài 20: REST Controller, JSON và DTO cho API danh sách
Java và Spring Boot – MVC và REST API
Spring Boot bài 21: REST CRUD: POST, PUT, DELETE và mã trạng thái
Java và Spring Boot – MVC và REST API
Spring Boot bài 22: Validation API, ProblemDetail và hợp đồng lỗi
Java và Spring Boot – MVC và REST API
Spring Boot bài 23: Gọi dịch vụ HTTP bằng RestClient và đặt timeout
Java và Spring Boot – MVC và REST API
Spring Boot bài 24: Gửi email và lập lịch tác vụ trong Spring Boot
Java và Spring Boot – MVC và REST API
Spring Boot bài 08: Fragment, layout và tài nguyên CSS trong Spring Boot
Java và Spring Boot – MVC và REST API
Spring Boot bài 25: Unit test Service với JUnit và Mockito
Java và Spring Boot – MVC và REST API
Spring Boot bài 10: Validation và BindingResult: báo lỗi ngay trên biểu mẫu

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 05: Đơn vị và kích thước: px, rem, %, min và max

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 02: Selector và class: chọn đúng phần tử cần sửa

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 01: Kết nối CSS với HTML và sửa quy tắc đầu tiên

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 20: Hoàn thiện website và sửa lỗi bằng DevTools

CSS cơ bản – 20 bài từ HTML đến website responsive với Flexbox, Grid và mobile-first

CSS cơ bản – Bài 03: Vì sao CSS không có tác dụng? Cascade và specificity

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×