BookRequest.java
Springboot/bookstore-api/src/main/java/com/example/bookstore/dto/BookRequest.java
package com.example.bookstore.dto;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
/**
* 「新增(POST)/完整更新(PUT)書籍」的請求 DTO(Data Transfer Object)。
*
* 【為什麼不直接用 Book Entity 接收請求?】
* 1. 安全:避免客戶端偷塞不該修改的欄位(如 id、createdAt),
* 這種攻擊稱為 Mass Assignment(大量賦值)漏洞。
* 2. 解耦:API 的欄位格式與資料庫結構可以各自獨立演進。
* 3. 驗證:輸入驗證規則集中寫在 DTO 上,Entity 保持乾淨。
*
* 【Java Record】
* record 是 Java 16+ 的「不可變資料類別」,
* 自動產生建構子、存取方法(title())、equals / hashCode / toString,
* 非常適合拿來當 DTO,省去大量樣板程式碼。
*
* 【Bean Validation 驗證註解】
* 需搭配 Controller 參數上的 @Valid 才會生效。
* 驗證失敗時會拋出 MethodArgumentNotValidException,
* 由 GlobalExceptionHandler 統一轉成 400 Bad Request 回應。
*/
public record BookRequest(
@NotBlank(message = "書名不可為空白") // 不可為 null、不可為空字串或全空白
@Size(max = 200, message = "書名長度不可超過 200 字")
String title,
@NotBlank(message = "作者不可為空白")
@Size(max = 100, message = "作者長度不可超過 100 字")
String author,
@NotBlank(message = "ISBN 不可為空白")
@Pattern(regexp = "^[0-9\\-]{10,17}$",
message = "ISBN 格式不正確(10~17 位的數字與連字號)")
String isbn,
@NotNull(message = "價格不可為空") // BigDecimal 用 @NotNull(@NotBlank 只能用在字串)
@DecimalMin(value = "0.0", message = "價格不可為負數")
BigDecimal price,
@NotNull(message = "庫存不可為空")
@Min(value = 0, message = "庫存不可為負數")
Integer stock,
@Size(max = 2000, message = "簡介長度不可超過 2000 字") // 沒加 @NotBlank → 此欄位可以不填
String description
) {
}
Bài viết liên quan
BookstoreApiApplication.java
BookstoreApiApplication.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/BookstoreApiApplication.java).
Đọc bài viết →DataInitializer.java
DataInitializer.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/DataInitializer.java).
Đọc bài viết →SecurityConfig.java
SecurityConfig.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/SecurityConfig.java).
Đọc bài viết →AuthController.java
AuthController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/AuthController.java).
Đọc bài viết →BookController.java
BookController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/BookController.java).
Đọc bài viết →ApiErrorResponse.java
ApiErrorResponse.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/dto/ApiErrorResponse.java).
Đọc bài viết →