S SmartDocs
系列: Springboot java 57 行 · 更新於 2026-08-14

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
) {
}

相關文章

Springboot java EN 更新於 2026-08-14

BookstoreApiApplication.java

BookstoreApiApplication.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/BookstoreApiApplication.java).

閱讀文章 →
Springboot java EN 更新於 2026-08-14

DataInitializer.java

DataInitializer.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/DataInitializer.java).

閱讀文章 →
Springboot java EN 更新於 2026-08-14

SecurityConfig.java

SecurityConfig.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/config/SecurityConfig.java).

閱讀文章 →
Springboot java EN 更新於 2026-08-14

AuthController.java

AuthController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/AuthController.java).

閱讀文章 →
Springboot java EN 更新於 2026-08-14

BookController.java

BookController.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/controller/BookController.java).

閱讀文章 →
Springboot java EN 更新於 2026-08-14

ApiErrorResponse.java

ApiErrorResponse.java — java source code from the Springboot learning materials (Springboot/bookstore-api/src/main/java/com/example/bookstore/dto/ApiErrorResponse.java).

閱讀文章 →