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 22: Validation API, ProblemDetail và hợp đồng lỗi
Java và Spring Boot – MVC và REST API

Spring Boot bài 22: Validation API, ProblemDetail và hợp đồng lỗi

  • 18-10-2026
  • Toanngo92
  • 0 Comments

Giáo trình Spring Boot MVC và REST API · Chương 9/12: REST API và hợp đồng HTTP · Bài 22/28 · Biên soạn tháng 10/2026.

← Bài 21 · Mục lục 12 chương · Bài 23 →

Mục lục

  • Mục tiêu bài học
  • Client cần lỗi có thể xử lý bằng chương trình
  • Thông báo theo trường và giới hạn thông tin
  • Những lỗi không phải do @Valid
  • Ghi hợp đồng trước khi có frontend riêng
  • 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

Trả lỗi JSON có cấu trúc, phân biệt lỗi đầu vào với lỗi không tồn tại và tránh lộ thông tin hệ thống.

Client cần lỗi có thể xử lý bằng chương trình

Một stack trace HTML không phù hợp với ứng dụng đang chờ JSON. Spring hỗ trợ ProblemDetail để biểu diễn lỗi theo chuẩn Problem Details for HTTP APIs. Các trường quen thuộc gồm type, title, status, detail và instance; có thể thêm thuộc tính mở rộng khi cần.

ApiErrors là @RestControllerAdvice chỉ áp dụng cho CourseApiController, để lỗi giao diện vẫn được render thành trang HTML. CourseNotFound đổi thành 404, dữ liệu không hợp lệ thành 400 và vi phạm toàn vẹn dữ liệu thành 409. Không dùng cùng một chuỗi “có lỗi xảy ra” cho mọi trường hợp mà bỏ mất ý nghĩa của HTTP.

Tệp trong mã nguồn mẫu: src/main/java/com/hocvietcode/academy/ApiErrors.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.

package com.hocvietcode.academy;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.http.*;
import org.springframework.dao.DataIntegrityViolationException;
@RestControllerAdvice(assignableTypes=CourseApiController.class)
public class ApiErrors {
    @ExceptionHandler(CourseNotFound.class) ProblemDetail missing(CourseNotFound e){return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND,e.getMessage());}
    @ExceptionHandler(IllegalArgumentException.class) ProblemDetail invalid(IllegalArgumentException e){return ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST,e.getMessage());}
    @ExceptionHandler(MethodArgumentNotValidException.class) ProblemDetail validation(MethodArgumentNotValidException e){
        ProblemDetail p=ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST,"Dữ liệu đầu vào không hợp lệ");
        p.setProperty("errors",e.getBindingResult().getFieldErrors().stream().map(x->x.getField()+": "+x.getDefaultMessage()).toList());return p;
    }
    @ExceptionHandler(DataIntegrityViolationException.class) ProblemDetail conflict(){return ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT,"Dữ liệu đang được sử dụng hoặc bị trùng");}
}

Thông báo theo trường và giới hạn thông tin

MethodArgumentNotValidException chứa các lỗi Bean Validation. Mẫu đưa chúng vào thuộc tính errors dưới dạng danh sách thông báo field: message. Một API lớn có thể dùng cấu trúc gồm field, code và message riêng để frontend dễ dịch và gắn đúng ô nhập; hãy giữ nhất quán trong cùng hợp đồng.

Không trả rejectedValue của trường nhạy cảm, câu SQL, tên bảng nội bộ hoặc exception.getStackTrace cho client. Lỗi DB trong mẫu được đổi thành mô tả trung tính. Phần chi tiết phục vụ vận hành nằm trong log được kiểm soát, không nằm trong response công khai.

Những lỗi không phải do @Valid

JSON sai cú pháp hoặc sai kiểu dữ liệu có thể gây HttpMessageNotReadableException trước khi validation chạy. Path/query sai kiểu gây lỗi chuyển đổi. Ứng dụng có thể mở rộng advice để chuẩn hóa các trường hợp đó; mẫu chỉ bảo đảm các nhánh lỗi đã được mô tả và kiểm thử, không tuyên bố mọi response lỗi của hệ thống đều có cùng envelope.

401/403 phát sinh ở Security filter thường không đi qua ControllerAdvice. Muốn hợp đồng lỗi JSON thống nhất cả tầng Security, cần AuthenticationEntryPoint và AccessDeniedHandler riêng. Đây là bước mở rộng có chủ đích, không phải bắt Exception chung trong Controller.

Ghi hợp đồng trước khi có frontend riêng

Với mỗi endpoint, ghi method, URL, query/body, quyền, CSRF, response thành công và lỗi có thể dự đoán. Có thể lưu mô tả bằng OpenAPI khi mở rộng; không cài thư viện Swagger/Springfox cũ của Boot 2 vào Boot 4 mà chưa kiểm tra tương thích. Bản mẫu chưa cài Swagger UI, nên không có đường dẫn giao diện tài liệu tự sinh.

Kiểm tra ít nhất JSON hợp lệ, tên trống, giá âm, danh mục không tồn tại và id không tồn tại. Test cần xác nhận status và Content-Type: application/problem+json, không chỉ tìm chữ lỗi trong body. Khi thay cấu trúc errors sau này, cập nhật test và client đồng thời.

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

  • Không trả lỗi nghiệp vụ bằng HTTP 200 chỉ để frontend khỏi vào nhánh catch.
  • ControllerAdvice không tự chuẩn hóa lỗi do mọi filter hoặc web server tạo ra.

Ghi nhớ

Hợp đồng lỗi rõ giúp frontend phản hồi đúng và giữ chi tiết hệ thống ở nơi phù hợp.

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

  • Error Responses / ProblemDetail

← Bài 21 · Mục lục 12 chương · Bài 23 →

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 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 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 26: Integration test MVC, API, database và Security

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
×