커뮤니티 프로젝트

Spring Validator, 추가 Validator

쭈녁 2022. 11. 16. 18:23

Spring Validator 사용

@Data
@Entity
public class Member {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    
    @NotEmpty(message = "아이디를 입력하세요")
    @Pattern(regexp = "^[a-z0-9]{4,20}$", message = "아이디는 영어 소문자와 숫자만 사용하여 4~20자리여야 합니다.")
    private String loginId;

    @NotEmpty(message = "닉네임을 입력하세요")
    @Length(min = 2, max = 16,message = "2자 이상 16자 이하입니다.")
    private String nickName;
    
    @NotEmpty(message = "비밀번호를 입력하세요")
    @Pattern(regexp = "^[a-zA-Z0-9]{4,20}$", message = "아이디는 영어 대,소문자와 숫자만 사용하여 4~20자리여야 합니다.")
    private String password;

    private String passwordConfirm;

    @NotEmpty(message = "이메일 주소를 입력하세요")
    @Email(message = "이메일 형식이 올바르지 않습니다.")
    private String email;
    
    private String profile;
    
    @CreationTimestamp
    private Timestamp created;
    
    @UpdateTimestamp
    private Timestamp updated;


}

엔티티에 에노테이션으로 Spring Validator 적용한다

필수 입력값에 @NotEmpty 적용하고 검증을 통과하지 못하는 경우에 메시지를 추가 

@Pattern으로 사용 가능한 패턴을 설정가능하고

@Length를 통해 길이를 지정할 수 있다 

 

Reposytory

@Repository
@Transactional
@RequiredArgsConstructor
public class JpaMemberRepository implements MemberRepository {
    private final SpringDataJpaMemberRepository repository;


    @Override

    public Member save(Member member) {
        repository.save(member);
        return member;

    }

    @Override
    public void update(Integer loginId, MemberUpdateDto updateDto) {
        Member findId = repository.findById(loginId).orElseThrow();
        findId.setNickName(updateDto.getNickName());
        findId.setPassword(updateDto.getPassword());
        findId.setProfile(updateDto.getProfile());
    }

    @Override
    public Optional<Member> findById(Integer id) {
        return repository.findById(id);
    }

    @Override
    public Optional<Member> findByMember(String loginId) {
        return repository.findAll().stream().filter(member->member.getLoginId().equals(loginId)).findFirst();
    }
    @Override
    public Optional<Member> findByNickName(String nickName) {
        return repository.findAll().stream().filter(member->member.getNickName().equals(nickName)).findFirst();
    }
    @Override
    public Optional<Member> findByEmail(String email) {
        return repository.findAll().stream().filter(member->member.getEmail().equals(email)).findFirst();
    }

Repository에 로그인ID, 닉네임, Email 로 객체를 찾을수 있도록 메서드를 만들어둔다(검증시 Repository에서 중복된 객체가 있는지 찾기 위함)

 

MemberValidator

@Component
@RequiredArgsConstructor
public class MemberValidator implements Validator {

    private final MemberRepository memberRepository;

    @Override
    public boolean supports(Class<?> clazz) {
        return Member.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        Member member = (Member) target;
        if (memberRepository.findByMember(member.getLoginId()).orElse(null)!=null) {
            errors.rejectValue("loginId","idUnique","ID 중복입니다.");
        }
        if (memberRepository.findByEmail(member.getEmail()).orElse(null)!=null) {
            errors.rejectValue("email","emailUnique","이메일 중복입니다.");
        }
        if (memberRepository.findByNickName(member.getNickName()).orElse(null)!=null) {
            errors.rejectValue("email","nickNameUnique","닉네임 중복입니다.");
        }
        if (!member.getPassword().equals(member.getPasswordConfirm())) {
            errors.rejectValue("password","confirm","비밀번호가 다릅니다.");
        }

    }
}

 

Validator를 상속하여 MemberValidator 클래스 생성

loginId, nickName, email 이 같으면 검증에 실패하도록 코드 작성

 

 

배운점

Opional로 객체를 찾아오게 작성하여 검증 로직에서 memberRepository.findByXXXX가 Null을 반환하지 않고 빈 객체를 반환해서 어떻게 만들어도 중복된 값이라고 나왔다. 그래서 처음엔 .get()을 사용해서 Null을 받아오려 했지만 noSuchException이 발생했고, .orElse로 일치하는 객체가 없으면 null을 반환하도록 설정하고 검증이 정상 작동하였다.

 

Optional은 객체가 없을시 NullPointException이 발생하지 않고 Null을 반환하지 않는다.

.get()은 value를 그대로 반환하고 NullPointException이 발생한다.

.orElse는 예외 시 대신하여 리턴할 대체 값을 지정하고,

.orElseGet은 인자로 받은  supplier를 실행한다.

.orElseThrow()로 NoSuchElementException 외에도 지정한 예외를 발생시킬 수 있다. 

 

'커뮤니티 프로젝트' 카테고리의 다른 글

댓글 기능 개발 (댓글 저장 부분)  (0) 2022.12.02
회원정보 수정  (0) 2022.11.30
JpaRepository, Querydsl, 게시물 CRUD  (1) 2022.11.24
Spring Security 회원가입 및 로그인  (0) 2022.11.23
Thymeleaf  (0) 2022.11.15