From 5a4b092fe3f6eb24aa05e791626ce4978ebb03f4 Mon Sep 17 00:00:00 2001 From: xxeol2 Date: Fri, 6 Oct 2023 14:33:45 +0900 Subject: [PATCH] =?UTF-8?q?[BE]=20refactor:=20request=20DTO=20Validation?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80(#462)=20(#463)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: StudentSendMailRequest validation 추가 * feat: StudentVerificateRequest validation 추가 * refactor: FestivalCreateRequest NotNull/NotBlank 제약조건 추가 * refactor: TicketValidationRequest NotNull -> NotBlank 로 변경 * refactor: LoginRequest NotNull -> NotBlank 로 변경 * feat: Request DTO Validation 추가 * refactor: 예외 메시지 일괄적이게 변경 * style: 개행 일괄 적용 * refactor: Controller의 Request Body @Valid 적용 * refactor: 상수 오타 수정 * refactor: Validation Error 메세지 자세하게 수정 --------- Co-authored-by: seokjin8678 --- .../com/festago/auth/dto/AdminLoginRequest.java | 4 ++++ .../com/festago/auth/dto/AdminSignupRequest.java | 4 ++++ .../java/com/festago/auth/dto/LoginRequest.java | 10 +++++++--- .../auth/dto/RootAdminInitializeRequest.java | 3 +++ .../common/exception/dto/ErrorResponse.java | 13 ++++++++++--- .../entry/dto/TicketValidationRequest.java | 6 ++++-- .../festival/dto/FestivalCreateRequest.java | 16 +++++++++++----- .../com/festago/presentation/AuthController.java | 3 ++- .../presentation/GlobalExceptionHandler.java | 2 +- .../festago/presentation/StudentController.java | 2 +- .../festago/school/dto/SchoolCreateRequest.java | 8 +++++--- .../festago/stage/dto/StageCreateRequest.java | 12 +++++++++--- .../student/dto/StudentSendMailRequest.java | 5 +++++ .../student/dto/StudentVerificateRequest.java | 7 ++++++- .../festago/ticket/dto/TicketCreateRequest.java | 14 ++++++++++---- .../festago/ticketing/dto/TicketingRequest.java | 4 +++- 16 files changed, 85 insertions(+), 28 deletions(-) diff --git a/backend/src/main/java/com/festago/auth/dto/AdminLoginRequest.java b/backend/src/main/java/com/festago/auth/dto/AdminLoginRequest.java index 1b71a7e8e..313977f5c 100644 --- a/backend/src/main/java/com/festago/auth/dto/AdminLoginRequest.java +++ b/backend/src/main/java/com/festago/auth/dto/AdminLoginRequest.java @@ -1,7 +1,11 @@ package com.festago.auth.dto; +import jakarta.validation.constraints.NotBlank; + public record AdminLoginRequest( + @NotBlank(message = "username은 공백일 수 없습니다.") String username, + @NotBlank(message = "password는 공백일 수 없습니다.") String password ) { diff --git a/backend/src/main/java/com/festago/auth/dto/AdminSignupRequest.java b/backend/src/main/java/com/festago/auth/dto/AdminSignupRequest.java index b35cf7337..02c689d9f 100644 --- a/backend/src/main/java/com/festago/auth/dto/AdminSignupRequest.java +++ b/backend/src/main/java/com/festago/auth/dto/AdminSignupRequest.java @@ -1,7 +1,11 @@ package com.festago.auth.dto; +import jakarta.validation.constraints.NotBlank; + public record AdminSignupRequest( + @NotBlank(message = "username은 공백일 수 없습니다.") String username, + @NotBlank(message = "password는 공백일 수 없습니다.") String password ) { diff --git a/backend/src/main/java/com/festago/auth/dto/LoginRequest.java b/backend/src/main/java/com/festago/auth/dto/LoginRequest.java index d05066b51..5872e77e1 100644 --- a/backend/src/main/java/com/festago/auth/dto/LoginRequest.java +++ b/backend/src/main/java/com/festago/auth/dto/LoginRequest.java @@ -1,11 +1,15 @@ package com.festago.auth.dto; import com.festago.auth.domain.SocialType; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; public record LoginRequest( - @NotNull(message = "socialType 은 null 일 수 없습니다.") SocialType socialType, - @NotNull(message = "acessToken 은 null 일 수 없습니다.") String accessToken, - @NotNull(message = "fcmToken 은 null 일 수 없습니다.") String fcmToken) { + @NotNull(message = "socialType은 null 일 수 없습니다.") + SocialType socialType, + @NotBlank(message = "acessToken은 공백일 수 없습니다.") + String accessToken, + @NotBlank(message = "fcmToken은 공백일 수 없습니다.") + String fcmToken) { } diff --git a/backend/src/main/java/com/festago/auth/dto/RootAdminInitializeRequest.java b/backend/src/main/java/com/festago/auth/dto/RootAdminInitializeRequest.java index e1d408d89..1f76a2921 100644 --- a/backend/src/main/java/com/festago/auth/dto/RootAdminInitializeRequest.java +++ b/backend/src/main/java/com/festago/auth/dto/RootAdminInitializeRequest.java @@ -1,6 +1,9 @@ package com.festago.auth.dto; +import jakarta.validation.constraints.NotBlank; + public record RootAdminInitializeRequest( + @NotBlank(message = "password는 공백일 수 없습니다.") String password ) { diff --git a/backend/src/main/java/com/festago/common/exception/dto/ErrorResponse.java b/backend/src/main/java/com/festago/common/exception/dto/ErrorResponse.java index 7c58f746e..a15d330fc 100644 --- a/backend/src/main/java/com/festago/common/exception/dto/ErrorResponse.java +++ b/backend/src/main/java/com/festago/common/exception/dto/ErrorResponse.java @@ -2,13 +2,16 @@ import com.festago.common.exception.ErrorCode; import com.festago.common.exception.FestaGoException; +import java.util.List; +import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; public record ErrorResponse( ErrorCode errorCode, - String message) { + String message +) { - private static final String NOT_CUSTOM_EXCPETION = "Validation failed"; + private static final String NOT_CUSTOM_EXCEPTION = "Validation failed"; public static ErrorResponse from(FestaGoException festaGoException) { return ErrorResponse.from(festaGoException.getErrorCode()); @@ -19,9 +22,13 @@ public static ErrorResponse from(ErrorCode errorCode) { } public static ErrorResponse from(ErrorCode errorCode, MethodArgumentNotValidException e) { - if (e.getMessage().startsWith(NOT_CUSTOM_EXCPETION)) { + List fieldErrors = e.getBindingResult().getFieldErrors(); + if (fieldErrors.isEmpty()) { return new ErrorResponse(errorCode, errorCode.getMessage()); } + if (e.getMessage().startsWith(NOT_CUSTOM_EXCEPTION)) { + return new ErrorResponse(errorCode, fieldErrors.get(0).getDefaultMessage()); + } return new ErrorResponse(errorCode, e.getMessage()); } } diff --git a/backend/src/main/java/com/festago/entry/dto/TicketValidationRequest.java b/backend/src/main/java/com/festago/entry/dto/TicketValidationRequest.java index e8aeba744..c006b24e6 100644 --- a/backend/src/main/java/com/festago/entry/dto/TicketValidationRequest.java +++ b/backend/src/main/java/com/festago/entry/dto/TicketValidationRequest.java @@ -1,8 +1,10 @@ package com.festago.entry.dto; -import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; public record TicketValidationRequest( - @NotNull(message = "code 는 null 일 수 없습니다.") String code) { + @NotBlank(message = "code는 공백일 수 없습니다.") + String code +) { } diff --git a/backend/src/main/java/com/festago/festival/dto/FestivalCreateRequest.java b/backend/src/main/java/com/festago/festival/dto/FestivalCreateRequest.java index 2d9c2b7fd..3fe810347 100644 --- a/backend/src/main/java/com/festago/festival/dto/FestivalCreateRequest.java +++ b/backend/src/main/java/com/festago/festival/dto/FestivalCreateRequest.java @@ -2,18 +2,24 @@ import com.festago.festival.domain.Festival; import com.festago.school.domain.School; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.time.LocalDate; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat.ISO; public record FestivalCreateRequest( - @NotNull(message = "name 은 null 일 수 없습니다.") String name, - @DateTimeFormat(iso = ISO.DATE) LocalDate startDate, - @DateTimeFormat(iso = ISO.DATE) LocalDate endDate, + @NotBlank(message = "name은 공백일 수 없습니다.") + String name, + @NotNull(message = "startDate는 null 일 수 없습니다.") + @DateTimeFormat(iso = ISO.DATE) + LocalDate startDate, + @NotNull(message = "endDate는 null 일 수 없습니다.") + @DateTimeFormat(iso = ISO.DATE) + LocalDate endDate, String thumbnail, - @NotNull(message = "schoolId는 null 일 수 없습니다.") Long schoolId -) { + @NotNull(message = "schoolId는 null 일 수 없습니다.") + Long schoolId) { public Festival toEntity(School school) { if (thumbnail == null || thumbnail.isBlank()) { diff --git a/backend/src/main/java/com/festago/presentation/AuthController.java b/backend/src/main/java/com/festago/presentation/AuthController.java index 012cecfe6..a287b33ec 100644 --- a/backend/src/main/java/com/festago/presentation/AuthController.java +++ b/backend/src/main/java/com/festago/presentation/AuthController.java @@ -8,6 +8,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; @@ -27,7 +28,7 @@ public class AuthController { @PostMapping("/oauth2") @Operation(description = "소셜 엑세스 토큰을 기반으로 로그인 요청을 보낸다.", summary = "OAuth2 로그인") - public ResponseEntity login(@RequestBody LoginRequest request) { + public ResponseEntity login(@RequestBody @Valid LoginRequest request) { LoginResponse response = authFacadeService.login(request.socialType(), request.accessToken()); memberFCMService.saveMemberFCM(response.accessToken(), request.fcmToken()); return ResponseEntity.ok() diff --git a/backend/src/main/java/com/festago/presentation/GlobalExceptionHandler.java b/backend/src/main/java/com/festago/presentation/GlobalExceptionHandler.java index d38dc11be..ac1922c13 100644 --- a/backend/src/main/java/com/festago/presentation/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/festago/presentation/GlobalExceptionHandler.java @@ -105,7 +105,7 @@ protected ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotV HttpHeaders headers, HttpStatusCode status, WebRequest request) { return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(ErrorResponse.from(ErrorCode.INVALID_REQUEST_ARGUMENT)); + .body(ErrorResponse.from(ErrorCode.INVALID_REQUEST_ARGUMENT, e)); } private void logInfo(FestaGoException e, HttpServletRequest request) { diff --git a/backend/src/main/java/com/festago/presentation/StudentController.java b/backend/src/main/java/com/festago/presentation/StudentController.java index 0672ece6a..96c19f53d 100644 --- a/backend/src/main/java/com/festago/presentation/StudentController.java +++ b/backend/src/main/java/com/festago/presentation/StudentController.java @@ -25,7 +25,7 @@ public class StudentController { @PostMapping("/send-verification") @Operation(description = "학교 인증 이메일을 전송한다.", summary = "학생 인증 이메일 전송") public ResponseEntity sendEmail(@Member Long memberId, - @RequestBody StudentSendMailRequest request) { + @RequestBody @Valid StudentSendMailRequest request) { studentService.sendVerificationMail(memberId, request); return ResponseEntity.ok() .build(); diff --git a/backend/src/main/java/com/festago/school/dto/SchoolCreateRequest.java b/backend/src/main/java/com/festago/school/dto/SchoolCreateRequest.java index 30312180c..cef320d8e 100644 --- a/backend/src/main/java/com/festago/school/dto/SchoolCreateRequest.java +++ b/backend/src/main/java/com/festago/school/dto/SchoolCreateRequest.java @@ -1,10 +1,12 @@ package com.festago.school.dto; -import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.NotBlank; public record SchoolCreateRequest( - @NotNull(message = "name 은 null 일 수 없습니다.") String name, - @NotNull(message = "domain 은 null 일 수 없습니다.") String domain + @NotBlank(message = "name은 공백일 수 없습니다.") + String name, + @NotBlank(message = "domain은 공백일 수 없습니다.") + String domain ) { } diff --git a/backend/src/main/java/com/festago/stage/dto/StageCreateRequest.java b/backend/src/main/java/com/festago/stage/dto/StageCreateRequest.java index 00691a8db..850a43242 100644 --- a/backend/src/main/java/com/festago/stage/dto/StageCreateRequest.java +++ b/backend/src/main/java/com/festago/stage/dto/StageCreateRequest.java @@ -6,9 +6,15 @@ import org.springframework.format.annotation.DateTimeFormat.ISO; public record StageCreateRequest( - @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime startTime, + @NotNull(message = "startTime은 null일 수 없습니다.") + @DateTimeFormat(iso = ISO.DATE_TIME) + LocalDateTime startTime, String lineUp, - @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime ticketOpenTime, - @NotNull(message = "festivalId 는 null 일 수 없습니다.") Long festivalId) { + @NotNull(message = "ticketOpenTime은 null일 수 없습니다.") + @DateTimeFormat(iso = ISO.DATE_TIME) + LocalDateTime ticketOpenTime, + @NotNull(message = "festivalId는 null 일 수 없습니다.") + Long festivalId +) { } diff --git a/backend/src/main/java/com/festago/student/dto/StudentSendMailRequest.java b/backend/src/main/java/com/festago/student/dto/StudentSendMailRequest.java index f58238144..fcb0563cf 100644 --- a/backend/src/main/java/com/festago/student/dto/StudentSendMailRequest.java +++ b/backend/src/main/java/com/festago/student/dto/StudentSendMailRequest.java @@ -1,7 +1,12 @@ package com.festago.student.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + public record StudentSendMailRequest( + @NotBlank(message = "username은 공백일 수 없습니다.") String username, + @NotNull(message = "schoolId는 null 일 수 없습니다.") Long schoolId ) { diff --git a/backend/src/main/java/com/festago/student/dto/StudentVerificateRequest.java b/backend/src/main/java/com/festago/student/dto/StudentVerificateRequest.java index 8e9053d1d..32a3a198f 100644 --- a/backend/src/main/java/com/festago/student/dto/StudentVerificateRequest.java +++ b/backend/src/main/java/com/festago/student/dto/StudentVerificateRequest.java @@ -1,5 +1,10 @@ package com.festago.student.dto; -public record StudentVerificateRequest(String code) { +import jakarta.validation.constraints.NotBlank; + +public record StudentVerificateRequest( + @NotBlank(message = "code는 공백일 수 없습니다.") + String code +) { } diff --git a/backend/src/main/java/com/festago/ticket/dto/TicketCreateRequest.java b/backend/src/main/java/com/festago/ticket/dto/TicketCreateRequest.java index 823bdca2b..31d740a08 100644 --- a/backend/src/main/java/com/festago/ticket/dto/TicketCreateRequest.java +++ b/backend/src/main/java/com/festago/ticket/dto/TicketCreateRequest.java @@ -7,9 +7,15 @@ import org.springframework.format.annotation.DateTimeFormat.ISO; public record TicketCreateRequest( - @NotNull(message = "stageId 는 null 일 수 없습니다.") Long stageId, - @NotNull(message = "ticketType 은 null 일 수 없습니다.") TicketType ticketType, - @NotNull(message = "amount 는 null 일 수 없습니다.") Integer amount, - @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime entryTime) { + @NotNull(message = "stageId는 null 일 수 없습니다.") + Long stageId, + @NotNull(message = "ticketType은 null 일 수 없습니다.") + TicketType ticketType, + @NotNull(message = "amount는 null 일 수 없습니다.") + Integer amount, + @NotNull(message = "entryTime은 null 일 수 없습니다.") + @DateTimeFormat(iso = ISO.DATE_TIME) + LocalDateTime entryTime +) { } diff --git a/backend/src/main/java/com/festago/ticketing/dto/TicketingRequest.java b/backend/src/main/java/com/festago/ticketing/dto/TicketingRequest.java index a2fe08a38..94f2e7a68 100644 --- a/backend/src/main/java/com/festago/ticketing/dto/TicketingRequest.java +++ b/backend/src/main/java/com/festago/ticketing/dto/TicketingRequest.java @@ -3,6 +3,8 @@ import jakarta.validation.constraints.NotNull; public record TicketingRequest( - @NotNull(message = "ticketId 는 null 일 수 없습니다.") Long ticketId) { + @NotNull(message = "ticketId는 null 일 수 없습니다.") + Long ticketId +) { }