ㅎㅇ
여기 읽다가 Model과 도메인 개념을 알아보고자 했는데 어쩌다보니 DDD 개념까지 엄청나게 커져서 결국 2일에 나눠 읽었다.
용어정리
내용정리
유효성 검사하기

홍대 맛집 아카이빙 프로젝트 #6.1에서...
밑에 TDD와 Validator만 알면 된다고했는데 TDD는 헤드퍼스트자바 5장에서 기초를 익혔고 대망의 Validator가 스프링인액션 2장의 주인공 중 하나다.
왜 쓸까?
폼에서 정보를 입력받기로했는데 이상한 값이 올 경우 (주소지에 노래가사를 적거나 하는 등) 로직이 이상하게 작동할 수 밖에 없다. 따라서 유효성 검사를 통해 입력된 정보가 올바른지 파악해야한다.
스프링은 빈 유효성 검사 API를 지원한다. 대략적으로는
- 유효성을 검사할 클래스에 검사 규칙 선언
- 컨트롤러 메서드에 검사 수행하는 것을 지정
- 에러를 보여주도록 폼 뷰 수정 (상태코드 반환방식의 경우엔 에러메시지를 수정하는 것이 좋을듯)
@NotNull
@Email
@Size(min=5, message="Name must be at least 5 characters long")
private String name;
뭐 이런식으로 구성할 수 있다.
@NotNull - 내용이 절대 Null일 수 없다.
@Email - 올바른 이메일 형식인지 검증용
@Size - 입력받을 객체의 최소길이를 설정
어노테이션은 다음과 같다. 위 3개의 어노테이션들은 message를 인자로 받을 수 있으며, 유효성 검증에 실패할 경우 에러코드와 에러메시지를 JSON 형태로 반환한다.
@NotBlank(message="")
private String name;
@CreditCardNumber
private String ccNumber;
@Pattern(regexp="^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$",
message="Must be formatted MM/YY")
private String date;
@Digits(integer=3, fraction=0, message="Invalid CVV")
private String ccCVV;
금융거래 등에서 쓸 때의 유효성 검사 어노테이션
@CreditCardNumber - 값이 룬(Luhn) 알고리즘 검사에 합격한 카드번호여야만한다. 다만 실제 존재하는 카드번호인지는 알 수 없다.
@Pattern - 정규 표현식을 지정하고 객체가 해당요소에 부합하는지를 검사한다. date에는 MM/YY 등의 형식을 검사로 사용할 수 없다.
정규표현식은 다음 글을 참고하면 좋다. 저 정규표현식은 입력된 문자열이 MM/YY 형식에서 MM이 0X 또는 1X 이며 / 이 /거나 \일 때, YY에 대해 유효성을 검증한다.
https://hamait.tistory.com/342
정규표현식 (Regex) 정리
정규표현식은 아주 가끔 쓰기때문에 항상 다시 볼때마다 헷갈리곤 하기에 주요 사용예를 내가 나중에 다시 봤을 때 편하도록 정리하여 보았다. 정규 표현식의 용어들정규 표현식에서 사용되는
hamait.tistory.com
@Digits - integer는 입력값이 정확하게 3자리인지, fraction은 소수점 이하 몇자리까지만 조건으로 설정한지를 본다. integer = 3이면 입력값이 세자리여야하며, fraction = 0 이면 소수점 이하 0자리까지 허용, 즉 정수만 허용한다는 것이다.
유효성 검사 시작하기
어쨌든 이러한 유효성검사는 서비스나 도메인이 아닌 컨트롤러에서 다뤄지며, 이를 위해서는 컨트롤러의 인자에 @Valid 어노테이션이 있어야한다.
@PostMapping("/signup")
public ResponseEntity<ResponseDTO> signupController (@Valid UserDTO userDTO) {
//로직
}
뭐 이런식으로
그러면 스프링MVC는 제출된 폼 데이터와 userDTO가 바인딩되고 코드가 실행되기 전 유효성 검사를 수행하게 된다.
예외처리
검사 도중 에러가 발생하면 Erros 객체에 저장된다. 그러면 예외처리를 하면 된다. Errors.hasErrors()가 쓰이며 에러가 있을 경우에는 true를 반환한다.
@PostMapping("/signup")
public ResponseEntity<ResponseDTO> signupController (@Valid UserDTO userDTO, Errors errors) {
if (errors.hasErrors()) {
//오류 생김. 로직 설정
}
}
이런식으로..
Errors는 리스트형태로 에러를 저장한다. 따라서 에러메시지 등을 가져오고 싶으면
errors.getAllErrors() //모든 에러 가져오기 (리스트형태)
error.getFieldErrors() //필드 관련 오류 가져오기. 괄호에 String 인자가 들어가면 해당 필드에서의 오류만 가져옴
errors.getFieldErrors().forEach(fieldError ->
response.addError(fieldError.getField(), fieldError.getDefaultMessage())
);
뭐.. 이런 식으로 사용할 수 있으려나싶다. 저거는 responseDTO의 Error가 Map 형식이어서 그런거고..
forEach 문법은 뭐지 하 도와줘 헤퍼자
암튼.. 이 뒤의 내용으로는 타임리프를 이용해 반환된 값을 HTML에 적용하는 방법이 있는데..
굳이? 싶긴하다. 어차피 지금은 응답코드를 반환만 시키면되는지라.. 나중에 프론트를 좀 배우고 다시 봐도 좋을 것 같다.
소감
오 꽤 좋은 내용이었다. 2장의 내용 대부분이 뷰(와 HTML), 컨트롤러, RequestMapping에 집중되어 있어서 솔직히 아직 HTML도 제대로 모르고 (기초문법은 1시간이면 배우겠으나 아직은 잘.. 모르겠다.) 응답코드를 반환하는 형식으로 CRUD 와 프로젝트 개발을 한 나는 뷰 관련된 내용은 별로 유용하게 쓰지 못할 것 같다. 다만 이외 내용에서는 유용하게 쓸 것 같다. 뭐 이 게시글의 거의 모든 내용인 유효성검사라던지...
'CS > 백엔드' 카테고리의 다른 글
| [2025백엔드] 스프링인액션 독서 #5 - 3장. 데이터로 작업하기 #3 (2) | 2025.08.04 |
|---|---|
| [2025백엔드] 스프링인액션 독서 #4 - 3장.데이터로 작업하기 2 (2) | 2025.08.01 |
| [2025백엔드] 스프링인액션 독서 #3 - 3장.데이터로 작업하기 1 (3) | 2025.07.29 |
| [2025 백엔드] 도메인과 Model, 도메인 주도 개발 (DDD) (1) | 2025.07.22 |
| [2025 백엔드] 스프링 인 액션 독서 #1 - 1장. 스프링 시작하기 (2) | 2025.07.21 |
