DTO(Domain Transfer Object) 유효성 검사
- 소프트웨어 개발에서 DTO 객체의 데이터가 요구사 항에 맞는 유효한 값인지 확인하는 과정
- DTO는 주로 데이터 전송을 위해 사용되는 객체로, 사용자 인터페이스(UI)와 비즈니스 로직 간의 데이터 전달을 담당.
DTO 유효성 검사는 다음과 같은 목적을 가지고 수행된다.
- 데이터의 유효성 확인: DTO 객체의 데이터 필드에 입력된 값이 올바른 형식, 범위, 제약 조건 을 충족하는지 확인
- ex) 숫자 필드에는 숫자 값이 입력되어야 하고, 문자열 필드 에는 특정 길이나 패턴이 적용되어야 한다.
- 비즈니스 규칙 준수 확인: DTO 객체의 데이터가 비즈니스 규칙을 준수하는지 검사
- ex) 주문을 나타내는 DTO에서 수량 필드는 음수가 될 수 없고, 가격 필드는 0 이상이어야 한다는 비즈니스 규칙이 있다면, 해당 규칙을 검증
- 보안 검사: DTO 객체의 데이터가 보안 요구사항을 충족하는지 확인
- ex) 사용자 의 비밀번호를 전송하는 DTO 객체의 경우, 암호화가 필요하거나 특정 문자열 패턴을 피해야 할 수도 있다.
요청DTO에 정규표현식 적용
public class UserRequest {
@Getter
@Setter
public static class JoinDTO {
@NotEmpty
@Pattern(regexp = "^[\\w._%+-]+@[\\w.-]+\\.[a-zA-Z]{2,6}$", message = "이 메일 형식으로 작성해주세요")
private String email;
@NotEmpty
@Size(min = 8, max = 20, message = "8에서 20자 이내여야 합니다.") @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[@#$%^&+=!~`<>,./?;:'\"\\[\\]{}\\\\()|_-])\\S*$", message= "영문, 숫자, 특수문자가 포함되어야하고 공백이 포함될 수 없습니다.")
private String password;
@NotEmpty
private String username;
public User toEntity() {
return User.builder()
.email(email)
.password(password)
.username(username)
.roles("ROLE_USER")
.build();
}
}
@Getter
@Setter
public static class LoginDTO {
@NotEmpty
@Pattern(regexp = "^[\\w._%+-]+@[\\w.-]+\\.[a-zA-Z]{2,6}$", message = "이 메일 형식으로 작성해주세요")
private String email;
@NotEmpty
@Size(min = 8, max = 20, message = "8에서 20자 이내여야 합니다.")
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[@#$%^&+=!~`<>,./?;:'\"\\[\\]{}\\\\()|_-])\\S*$", message = "영문, 숫자, 특수문자가 포함되어야하고 공백이 포함될 수 없습니다.")
private String password;
}
@Getter
@Setter
public static class EmailCheckDTO {
@NotEmpty
@Pattern(regexp = "^[\\w._%+-]+@[\\w.-]+\\.[a-zA-Z]{2,6}$", message = "이 메일 형식으로 작성해주세요")
private String email;
}
}
@NotNull : Null 값 체크
@NotEmpty : Null, "" 체크
@NotBlank : Null, "", 공백을 포함한 빈값 체크
@Pattern(regexp = "정규식", message = "영문, 숫자, 특수문자가 포함되어야하고 공백이 포함될 수 없습니다.")
@Size(min = 8, max = 20, message = "8에서 20자 이내여야 합니다.")
Request DTO의 유효성 검사에서 사용할 수 있는 어노테이션이다.
컨트롤러에서 정규표현식 체크
요청 DTO 앞에 @Valid 어노테이션을 추가하고, 요청 DTO 바로 뒤에 Errors erros 파라메터를 추가한다.
스프링의 DispatcherServlet은 join() 메서드가 실행되기 직전에 요청 DTO의 정규표현식 문법을 검사하고 에러가 발생하면, Errors erros에 문법이 틀린 모든 에러를 담아서 주입해준다.
주의: DTO 바로 뒤에 Error errors를 작성해야 한다. 중간에 다른 파라미터가 들어가면 에러가 뜬다.
@PostMapping("/join")
public ResponseEntity<?> join(@RequestBody @Valid UserRequest.JoinDTO joinDTO,
Errors errors) {
User user = User.builder()
.email(joinDTO.getEmail())
.password(passwordEncoder.encode(joinDTO.getPassword()))
.username(joinDTO.getUsername())
.roles("ROLE_USER")
.build();
userRepository.save(user);
return ResponseEntity.ok().body(ApiUtils.success(null));
}
에러메시지를 반환 할 때는 굳이 모든 메시지를 반환할 필요는 없다.
하나만 반환해주어도 된다. -> 클라이언트에서 이미 오류검사가 이루어짐, 비정상접속이 가능성 있음, 하나씩만 알려주어도 해결가능
정규식 표현
정규식 자체를 외울 필요는 없다. 자주 쓰이지 않기 때문에 사용할 당시에 GPT나 검색을 통해 알아본 후 자체 검증을 거친 후 사용 하면 된다.
RegExr: Learn, Build, & Test RegEx
RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).
regexr.com
테스트 코드
@Test
public void 한글은안된다_test() throws Exception {
String value = "abcᅡ";
boolean result = Pattern.matches("^[^ᄀ-하-ᅵ가-힣]*$", value);
System.out.println("테스트 : " + result);
Assertions.assertTrue(result);
}
'I leaned > 스프링,스프링부트' 카테고리의 다른 글
DTO (0) | 2023.07.17 |
---|---|
컨트롤러와 서비스의 책임 (0) | 2023.07.17 |
JPA N+1문제 와 Fetch join (0) | 2023.07.10 |
컨트롤러에 비즈니스로직을 넣으면 안되는 이유 (0) | 2023.07.04 |
데이터의 변환과 검증 (0) | 2023.05.30 |