diff --git a/pom.xml b/pom.xml index 44be38c..1c8f67d 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,10 @@ 0.2.0 + + org.hibernate.validator + hibernate-validator + org.springframework.boot spring-boot-starter diff --git a/src/main/java/org/bookstore/controller/BookController.java b/src/main/java/org/bookstore/controller/BookController.java index 5d76e9c..d6ded4a 100644 --- a/src/main/java/org/bookstore/controller/BookController.java +++ b/src/main/java/org/bookstore/controller/BookController.java @@ -1,5 +1,6 @@ package org.bookstore.controller; +import jakarta.validation.Valid; import java.util.List; import lombok.RequiredArgsConstructor; import org.bookstore.dto.BookDto; @@ -31,13 +32,13 @@ public BookDto getBookById(@PathVariable Long id) { } @PostMapping - public BookDto createBook(@RequestBody CreateBookRequestDto bookRequestDto) { + public BookDto createBook(@RequestBody @Valid CreateBookRequestDto bookRequestDto) { return bookService.save(bookRequestDto); } @PutMapping("/{id}") public void updateBookById(@PathVariable Long id, - @RequestBody CreateBookRequestDto bookRequestDto) { + @RequestBody @Valid CreateBookRequestDto bookRequestDto) { bookService.updateBookById(id, bookRequestDto); } diff --git a/src/main/java/org/bookstore/dto/CreateBookRequestDto.java b/src/main/java/org/bookstore/dto/CreateBookRequestDto.java index 70977a2..79997a1 100644 --- a/src/main/java/org/bookstore/dto/CreateBookRequestDto.java +++ b/src/main/java/org/bookstore/dto/CreateBookRequestDto.java @@ -1,14 +1,20 @@ package org.bookstore.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.PositiveOrZero; import java.math.BigDecimal; import lombok.Data; @Data public class CreateBookRequestDto { private Long id; + @NotBlank private String title; + @NotBlank private String author; + @NotBlank private String isbn; + @PositiveOrZero private BigDecimal price; private String description; private String coverImage; diff --git a/src/main/java/org/bookstore/exceptions/GlobalExceptionHandler.java b/src/main/java/org/bookstore/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000..803d5db --- /dev/null +++ b/src/main/java/org/bookstore/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,46 @@ +package org.bookstore.exceptions; + +import java.time.LocalDateTime; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { + @Override + protected ResponseEntity handleMethodArgumentNotValid( + MethodArgumentNotValidException ex, + HttpHeaders headers, + HttpStatusCode status, + WebRequest request) { + Map body = new LinkedHashMap<>(); + body.put("time", LocalDateTime.now()); + body.put("status", HttpStatus.BAD_REQUEST); + List error = ex.getBindingResult().getAllErrors() + .stream() + .map(this::getErrorMessage) + .collect(Collectors.toList()); + body.put("errors", error); + return new ResponseEntity<>(body, headers, status); + } + + private String getErrorMessage(ObjectError objectError) { + if (objectError instanceof FieldError) { + String field = ((FieldError) objectError).getField(); + String message = objectError.getDefaultMessage(); + return field + " " + message; + } + return objectError.getDefaultMessage(); + } +}