Spring에서 @NotBlank, @Email등 여러 템플릿에 맞게 Validation을 넣을 수 있다.
하지만 추가적으로 패스워드 규칙과 같이 별도 체크할 validator가 필요할 때 만들어서 사용해야 하는데 만들어서 지정해보는 작업을 해보자.
1. Controller
요청을 받을 DTO앞에 @Valid 어노테이션을 추가해야한다.
1 2 3 4 5 6 7 8 9 10 11 | /** * 회원가입 * * @param reqDto * @return * @throws Exception */ @RequestMapping("/join") public ResponseEntity<?> join(@Valid UserDto reqDto) throws Exception { return ResponseEntity.ok(userService.insertUser(reqDto)); } | cs |
2. Annotation 추가
Validation 사용을 위해서 필드에 @NotNull, @NotBlank와 같이 어노테이션을 붙혀줘야한다. 그래서 Custom Validation을 만들고 필드에 붙히기 위해서 어노테이션을 만들어줘야한다. 기본적으로 표현되는 메시지는 설정을 진행한 messageSource에서 가져오는데 가져오지 못하면 default로 설정한 메시지를 출력하게 할 수있다. 그리고 기존에 어노테이션 만들던 방법과 조금 다른 부분이 있는데 바로 @Constraint 필드이다. 여기서 지정하는 설정은 어떤 검증 클래스를 사용해서 필드의 값을 검증할 건지 지정해준다. 이 방법을 위해서는 ConstraintValidator 인터페이스를 구현한 클래스를 지정해줘야한다. 아래에서 확인해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package com.wedul.common.annotation; import com.wedul.common.validation.PasswordValidator; import javax.validation.Constraint; import java.lang.annotation.*; @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = {PasswordValidator.class}) public @interface PasswordCheck { String message() default "";
} | cs |
3. Validator 추가
ConstraintValidator 인터페이스를 구현해주면서 지정해주는 제네릭 값 첫 번째에는 2번에서 만든 애노테이션 객체가 들어가고 두 번째 값에는 이 어노테이션 값이 붙어서 Constraint 작업을 진행할 필드의 데이터 유형을 넣는다. (패스워드라면 String) 만약 특정하기 어려운 어노테이션인경우 Object를 붙여서 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.wedul.common.validation; import com.wedul.common.annotation.PasswordCheck; import org.apache.commons.lang.StringUtils; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; /** * 패스워드 validation * * @author wedul * @since 2018-12-23 **/ public class PasswordValidator implements ConstraintValidator<PasswordCheck, String> { @Override public boolean isValid(String value, ConstraintValidatorContext context) { // 6자리이상 대문자 포함 return StringUtils.isNotBlank(value) && value.length() >= 6 && value.chars().boxed().filter(data -> Character.isUpperCase(data)).findAny().isPresent(); } } | cs |
4. DTO 적용
적용하고자하는 곳에 추가한 필드에 넣어보자!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | package com.wedul.wedulpos.user.dto; import com.wedul.common.annotation.PasswordCheck; import com.wedul.common.dto.CommonDto; import com.wedul.common.util.HashUtil; import lombok.*; import org.apache.ibatis.type.Alias; import javax.persistence.*; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.io.Serializable; /** * User정보 Dto * * @author wedul * @date 2017. 11. 4. * @name UserDto */ @Alias("UserDto") @Data @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode(callSuper=false) @Entity @Table(name = "user") public class UserDto extends CommonDto implements Serializable { @Id @GeneratedValue private int userId; @Column(nullable = false) private String nickname; @Column(nullable = false) @NotBlank(message = "user.login.message.mustemail") @Email(message = "user.login.message.validation_email") private String email; @Column(nullable = true) @PasswordCheck(message = "user.join.message.password") private String password = ""; @Column(nullable = true) private String snsId; @Column(nullable = false) private boolean isAdmin = false; public UserDto(String email) { this.email = email; } public UserDto(String email, String password) { this.email = email; this.password = password; } public UserDto(String email, String password, boolean isAdmin) { this.email = email; this.password = password; this.isAdmin = isAdmin; } public UserDto(String email, String password, String nickname, boolean isAdmin) { this.email = email; this.password = password; this.nickname = nickname; this.isAdmin = isAdmin; } public String getEcPassword() { return HashUtil.sha256(this.password); } } | cs |
validation 오류 발생시 상황에 맞는 문구가 나올 수 있도록 별도의 설정을 해줘야 하는데 그 부분은 다음시간에 정리해서 올려보자.
우선 Custom Validation을 만든부분만 정리하자.
'web > Spring' 카테고리의 다른 글
Spring Reactive Web Application (0) | 2019.01.12 |
---|---|
생성한 Custom validation으로 에러메시지 출력하기 (4) | 2018.12.25 |
inteliij 사용 시 related gradle configuration 설정을 찾지 못할 경우 해결방법 (2) | 2018.12.19 |
[공유] spring에서 생성자 의존성 주입 (0) | 2018.11.19 |
Spring Boot Cross Domain 처리 (0) | 2018.10.04 |