Validation
요청 데이터의 유효성 검증(사용자의 아이디의 길이라던지 정규표현식에 만족하는지에 대한 검증 등등)과 비즈니스 로직은 보통 Service 로직에 담겨있습니다. DB 중복 체크 등 비즈니스 로직은 서비스에 두고, 이 데이터의 유효성 검사를 스프링 부트에서 제공해주는 Validation 기능을 이용하면 손쉽게 검증할 수 있을 뿐더러 서비스에는 오직 핵심 비즈니스 로직만 둘 수 있는 장점을 가져갈 수 있을 것 같습니다. 아래 실습을 통해 자세하게 알아보겠습니다.
개발환경
- SpringBoot 2.7.9
- JDK 11
- Gradle
의존성 추가
SpringBoot 2.3.0 이상부터는 의존성이 포함되어 있지 않기 때문에 직접 추가해줘야 합니다.
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
Controller
@RestController
public class TestController {
@PostMapping
public Response saveAccount(@Valid @RequestBody SaveDto dto){ // ***
// logic
}
}
public class SaveDto {
@NotBlank(min=6, message="유저명은 6자리 이상입니다.")
private String username;
@NotBlank(min=8, message="비밀번호는 8자리 이상입니다.")
private String password;
}
컨트롤러에서 RequestBody에 받는 객체에 @Valid 어노테이션을 붙이면 끝입니다. SaveDto의 프로퍼티에 대한 제약사항은 각 필드에 작성해주시면 됩니다.
@NotBlank 이 외에도 여러 검증을 할 수 있습니다. 더 다양한 검증을 하고 싶다면 여기를 참조해주세요.
@Null | null만 허용 |
@NotNull | null 허용 X ””, “ “는 허용 |
@NotEmpty | null, “” 허용 X ” “는 허용 |
@NotBlank | null, “”, “ “ 허용 X |
Java Bean Validation Basics | Baeldung
Learn the basics of Java Bean validation, the common annotations and how to trigger the validation process.
www.baeldung.com
@ExceptionHanlder를 이용한 응답 처리
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Map<String, String> field(MethodArgumentNotValidException e) {
HashMap<String, String> response = new HashMap<>();
e.getFieldErrors().forEach(error -> {
response.put(error.getField(), error.getDefaultMessage());
});
return response;
}
테스트
테스트 코드를 통해 유효성 검사를 실패했을 때 올바른 응답값이 오는지 확인해보겠습니다.
@WebMvcTest
class ValidationControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void validationExceptionTest() throws Exception {
// given
String data = "{\"username\": \"user\", \"password\": \"pass\"}";
// when & then
mockMvc.perform(post("/users")
.contentType(MediaType.APPLICATION_JSON)
.content(data))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(jsonPath("username").exists())
.andExpect(jsonPath("password").exists());
}
}
정상적으로 테스트가 통과하는 것을 확인할 수 있습니다!
감사합니다.
REFERENCES
Validation in Spring Boot | Baeldung
Learn how to validate domain objects in Spring Boot using Hibernate Validator, the reference implementation of the Bean Validation framework.
www.baeldung.com
Java Bean Validation Basics | Baeldung
Learn the basics of Java Bean validation, the common annotations and how to trigger the validation process.
www.baeldung.com