-
[Spring Boot] 유효성 검사 처리 (Custom Validation)Spring Boot/기타 2022. 6. 6. 18:46반응형
1. DateValid 구현
DateValid.java
package com.example.customvalidation.annotiaon; import com.example.customvalidation.validator.DateValidator; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Documented @Constraint(validatedBy = DateValidator.class) @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface DateValid { String message() default "6자리의 yyyyMMdd 형식이어야 합니다."; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; String pattern() default "yyyyMMdd"; }
2. DateValidator 구현
DateValidator.java
package com.example.customvalidation.validator; import com.example.customvalidation.annotiaon.DateValid; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import lombok.extern.slf4j.Slf4j; @Slf4j public class DateValidator implements ConstraintValidator<DateValid, String> { private String pattern; @Override public void initialize(DateValid constraintAnnotation) { this.pattern = constraintAnnotation.pattern(); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { try { LocalDate.from(LocalDate.parse(value, DateTimeFormatter.ofPattern(this.pattern))); } catch (DateTimeParseException e) { log.error("DateValidator : {}", e); return false; } return true; } }
3. ValidatedController 구현
ValidatedController.java
package com.example.customvalidation.controller; import com.example.customvalidation.dto.ValidatedDto; import javax.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController public class ValidatedController { @PostMapping("/validated/date") public String validatedDate( @Valid @RequestBody ValidatedDto.Request validationRequest ) { log.info("validationRequest: {}", validationRequest); return "postValidation"; } }
4. ValidatedDto 구현
ValidatedDto.java
package com.example.customvalidation.dto; import com.example.customvalidation.annotiaon.DateValid; import com.fasterxml.jackson.annotation.JsonProperty; import javax.validation.constraints.AssertFalse; import javax.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; public class ValidatedDto { @Getter @Setter @Builder @AllArgsConstructor @NoArgsConstructor @ToString public static class Request { @JsonProperty("id") private Long id; @NotBlank @JsonProperty("title") private String title; @NotBlank @JsonProperty("description") private String description; @AssertFalse @JsonProperty("completed") private Boolean completed; @DateValid(message = "8자리의 yyyy-MM-dd 형식이어야 합니다.", pattern = "yyyy-MM-dd") @JsonProperty("created_date") private String createdDate; @DateValid(message = "8자리의 yyyy-MM-dd 형식이어야 합니다.", pattern = "yyyy-MM-dd") @JsonProperty("updated_date") private String updateDate; } @Getter @Setter @AllArgsConstructor @NoArgsConstructor @ToString public class Response { @JsonProperty("id") private Long id; @JsonProperty("title") private String titile; @JsonProperty("description") private String description; @JsonProperty("completed") private Boolean completed; @JsonProperty("created_date") private String createdDate; @JsonProperty("updated_date") private String updateDate; } }
5. ValidatedControllerTest 구현
ValidatedControllerTest.java
package com.example.customvalidation.controller; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.example.customvalidation.dto.ValidatedDto; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @AutoConfigureMockMvc @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Disabled class ValidatedControllerTest { @Autowired MockMvc mockMvc; @Autowired ObjectMapper objectMapper; @DisplayName("validatedDate_유효성 검증 성공_응답 코드:200") @Test void testValidatedDate() throws Exception { // Given & When String url = "/validated/date"; ValidatedDto.Request validatedRequest = ValidatedDto.Request.builder() .title("title") .description("description") .completed(false) .createdDate("2022-06-06") .updateDate("2022-06-06") .build(); ResultActions resultActions = mockMvc.perform( post(url) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validatedRequest)) ); // Then resultActions .andExpect(status().isOk()) .andDo(print()); } @DisplayName("validatedDate_유효성 검증 실패_응답 코드:400") @Test void testValidatedDateFail() throws Exception { // Given & When String url = "/validated/date"; ValidatedDto.Request validatedRequest = ValidatedDto.Request.builder() .title("title") .description("description") .completed(false) .createdDate("20220606") .updateDate("20220606") .build(); ResultActions resultActions = mockMvc.perform( post(url) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(validatedRequest)) ); // Then resultActions .andExpect(status().isBadRequest()) .andDo(print()); } }
소스 코드는 Github Repository - https://github.com/tychejin1218/custom-validation 를 참조하세요.
참고 : https://www.baeldung.com/spring-mvc-custom-validator반응형'Spring Boot > 기타' 카테고리의 다른 글
[Spring Boot] Amazon S3로 파일 업로드 및 삭제 (0) 2023.01.27 [Spring boot] Database가 Replication일 때 DataSource 설정 (2) 2023.01.17 [Spring Boot] Spring Data JPA + QueryDSL 설정 (2) 2023.01.15 [Spring Boot] 에러 메시지 처리 (Custom Exception) (0) 2022.06.06 [Spring Boot] MockMvc 사용 시 한글이 깨지는 현상 (0) 2021.08.29