개발을 하다보면 CRUD 기반으로 로직을 짠다. 실무에서는 CRUD 기반으로 개발하는것 보다는 유효성검사나 예외처리 같은 부분에 더 많은 시간을 쓴다고 한다.
Validation(유효성검사)
, 후처리는 Exception Handler
로 처리한다.Validatino 라이브러리를 pomxml 에 추가해줘야 한다.
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.4.4</version>
</dependency>
DB와 직접적으로 연결되는 Domain 에는 JPA 가 제공하는 Validaton 기능들을 사용해야 한다. 이 라이브러리에서 사용하는 Validation 은 DTO와 같은 곳에 사용한다 !!
@Data
: Getter , Setter , toString() 등등 편리한 어노테이션을 한꺼번에 제공
@Size(min = 2, max = 20)
: 최소 2자 에서 최대 20자까지만 받는다
@NotBlank
: Null, 빈문자열, 공백만 있는 문자는 못받는다
@Data
public class SignupDto {
@Size(min = 2,max = 20) //길이 20자 제한
@NotBlank
private String username;
@NotBlank //null, 빈문자열, 공백만있는 문자불가
private String password;
@NotBlank
private String email;
@NotBlank
private String name;
//생략...
}
@Valid
를 꼭 붙여준다.BindingResult
라는 객체를 파라미터로 넣는다. (반드시 @Valid
하는 객체 뒤에 와야 한다 !!)BindingResult
는 Validation 을 했을 때 오류를 담는 객체이다.CustomValidationException
이라는 개발자가 만든 예외를 던져준다 !@PostMapping("/auth/signup")
public String signUp(@Valid SignupDto signupDto, BindingResult bindingResult){
if(bindingResult.hasErrors()){ // Validation 후 error 가 있다면
Map<String, String> errorMap = new HashMap<>();
for (FieldError error : bindingResult.getFieldErrors()) {
errorMap.put(error.getField(),error.getDefaultMessage());
}
throw new CustomValidationException("유효성 검사 실패함",errorMap);
}else{
User user = signupDto.toEntity();
User userEntity = authService.회원가입(user);
return "auth/signin"; //로그인 페이지로 이동
}
}
CustomValidationException
은 개발자가 따로 예외처리를 하기 위해RuntimeException
을 상속받아 만든 클래스이다.
public class CustomValidationException extends RuntimeException{
// 객체를 구분할 때 !!(JVM 이 구분한다고 한다) 중요하진않음.
private static final long serialVersionUID = 1L;
private Map<String,String> errorMap = new HashMap<>();
public CustomValidationException(String message, Map<String, String> errorMap) {
super(message);
this.errorMap = errorMap;
}
public Map<String, String> getErrorMap() {
return errorMap;
}
}
ControllerExceptionHandler
가 개발자가 짜놓은 예외가 터지면 가로채서 로직을 실행한다.
@ControllerAdvice
: 예외(Exception)이 발생하면 이 어노테이션이 붙은 클래스가 가로챈다.
@ExceptionHandler(예외 타입)
: 예외타입이 발생하는 모든 오류를 해당 어노테이션이 붙은 메서드가 가로채서 로직을 실행한다.
@RestController
@ControllerAdvice //Exception 이 발생하면 어노테이션이 붙은 클래스가 가로챈다.
public class ControllerExceptionHandler {
@ExceptionHandler(CustomValidationException.class) //RuntimeException 이 발생하는 모든 오류를 이 메서드가 가로챈다.
public Map<String,String> validationException(CustomValidationException e){
return e.getErrorMap();
}
}