109p ~ 111p
유효성 검사를 해야할 조건은 아래와 같다.
ISBN은 올바른 형식으로 정의되어야 한다(ISBN-10 or 13)
제목, 저자, 가격은 반드시 있어야하고 가격은 0보다 큰 값이어야 한다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.1'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.polarbookshop'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-validation' // 유효성 검사 의존성 추가
}
tasks.named('test') {
useJUnitPlatform()
}
유효성 검사를 위한 디펜던시 추가
gradlew build --refresh-dependencies 로 빌드 한 번 해줘야 적용된다.
빌드는 성공했는데 javax.validation.constraints.* 를 인식못하는 것... 챗지선생에게 물어보니
스프링부트3.n 이후 버전에선 javax.validation 대신 jakarta.validation 을 써야한다고 함. 수정해주니 잘 인식된다.
수정 완료
package com.polarbookshop.catalogservice.domain;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Positive;
// 도메인 객체(Entity) 정의
// 도메인 모델은 불가변 객체인 레코드로 구현
public record Book(
@NotBlank(message = "The book ISBN must be defined")
@Pattern(
regexp = "^[0-9]{10}|[0-9]{13}$",
message = "The ISBN format must be valid"
)
String isbn, // 책 고유번호(식별)
@NotBlank(message = "The book title must be defined")
String title,
@NotBlank(message = "The book author must be defined")
String author,
@NotBlank(message = "The book price must be defined")
// @Positive: 널 값이어서는 안되고 0보다 큰 값이어야함.
@Positive(message = "The book price must be greater than zero")
Double price
) { }
스프링에게 BookController 클래스의 Book 객체에 대한 유효성을 검사하도록 지시.
=> @RequestBody가 메서드 인수로 지정될 때 @Valid 애너테이션 사용하여 지시.
package com.polarbookshop.catalogservice;
import com.polarbookshop.catalogservice.domain.Book;
import com.polarbookshop.catalogservice.domain.BookService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("books")
public class BookController {
private final BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService;
}
@GetMapping
public Iterable<Book> get() {
return bookService.viewBookList();
}
// 루트 패스 URI에 추가되는 URI 템플릿 변수("/books/{isbn}")
@GetMapping("{isbn}")
public Book getByIsbn(@PathVariable String isbn) {
return bookService.viewBookDetails(isbn);
}
@PostMapping
// 책이 성공적으로 생성되면 201 상태코드를 반환
@ResponseStatus(HttpStatus.CREATED) // 성공시 201 상태코드 반환
//@RequestBody는 웹 요청의 본문을 메서드 변수로 바인드
public Book post(@Valid @RequestBody Book book) {
return bookService.addBookToCatalog(book);
}
@DeleteMapping("{isbn}")
@ResponseStatus(HttpStatus.NO_CONTENT) // 성공시 204 상태코드 반환
public void delete(@PathVariable String isbn, @RequestBody Book book) {
bookService.removeBookFromCatalog(isbn);
}
@PutMapping("{isbn}")
//@RequestBody : 요청 본문(JSON 형식의 데이터를 Book 객체로 변환)하여 컨트롤러 메서드에 전달
public Book put(@PathVariable String isbn, @Valid @RequestBody Book book) {
return bookService.editBookDetails(isbn, book);
}
}
'Cloud Native Spring in Action' 카테고리의 다른 글
JUnit5를 이용한 단위 테스트 (0) | 2025.02.07 |
---|---|
중앙식 예외 핸들러와 이를 이용한 오류 처리 (0) | 2025.02.06 |
스프링 MVC를 이용한 REST API 구현, 그리고 Httpie 설치와의 사투 (0) | 2025.02.06 |
스프링 MVC를 이용한 RESTful 애플리케이션 구축(2) (1) | 2025.02.05 |
스프링 MVC를 이용한 RESTful 애플리케이션 구축(1) (3) | 2025.02.05 |