728x90
반응형
회원가입시 중복 닉네임, 중복 아이디인지 검증하고,
해당하는 조건에 충족한지 검증한다.
또한, 프론트엔드에서 한번 검증하고, 혹시모를 경우를 대비해 백엔드에서 검증하는 절차를 거친다.
AccountController
package com.demo.account;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import lombok.RequiredArgsConstructor;
@Controller
@RequiredArgsConstructor
public class AccountController {
private final SignUpFormValidator signUpFormValidator;
@InitBinder ("signUpForm")
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.addValidators(signUpFormValidator);
}
// sign-up 페이지에 연결된다면
@GetMapping("/sign-up")
public String signUpForm(Model model) {
// model.addAttribute(new SignUpForm()); 생략 가능
model.addAttribute("signUpForm", new SignUpForm());
return "account/sign-up";
}
// 스프링부트 자동설정에 의해
// templates에 존재하는 view인 account/sign-up을 리턴한다.
@PostMapping("/sign-up") // 복합객체는 본디 ModelAttribute로 받지만, 생략가능
public String signUpSubmit(@Valid @ModelAttribute SignUpForm signUpForm, Errors errors) {
if (errors.hasErrors()) {
return "account/sign-up";
}
// SignUpForm 도메인에 Valid를 위한 처리 필요
// @InitBinder를 이용해 대체
// signUpFormValidator.validate(signUpForm, errors);
// if (errors.hasErrors()) {
// return "account/sign-up";
// }
// -> 자동으로 SignUpForm 검증을 한다.
// TODO 회원 가입 처리 valid에 안걸리면 회원가입
return "redirect:/";
}
}
SignUpFormValidate
package com.demo.account;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import lombok.RequiredArgsConstructor;
//의존성 주입을 autowired 사용하지않고, bean과 RequiredArgsConstructor을 이용
//bean 어노테이션
@Component
//롬복을 이용해 private final만 생성자로 자동생성 -> 선택가능하므로 사용
@RequiredArgsConstructor
//public SignUpFormValidator(AccountRepository accountrepository) {
// this.accountrepository = accountrepository;
//}
public class SignUpFormValidator implements Validator{
//회원정보를 저장해 중복을 검사하는 변수
private final AccountRepository accountRepository;
//ctrl + shift + Y 소문자로 변환, ctrl+n 해당 이름으로 클래스생성
@Override
public boolean supports(Class<?> aClass) {
// TODO Auto-generated method stub
return aClass.isAssignableFrom(SignUpForm.class);
//SignUpForm 타입의 인스턴스를 검사
}
@Override
public void validate(Object o, Errors errors) {
// TODO email, nickname -> accountrepository에서 조회
SignUpForm signUpForm =(SignUpForm) o;
if (accountRepository.existsByEmail(signUpForm.getEmail())) {
errors.rejectValue("email", "invaild.email", new Object[] {signUpForm.getEmail()}, "이미 사용중인 이메일입니다. ");
}
//bean을 주입받아야 하므로, bean끼리만 가능
if (accountRepository.existsByNickname(signUpForm.getNickname())) {
errors.rejectValue("nickname", "invaild.nickname", new Object[] {signUpForm.getNickname()}, "이미 사용중인 닉네임입니다. ");
}
}
//실제 DB에서 조회해 중복여부를 파악
}
Account Repository
package com.demo.account;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
import com.demo.domain.Account;
//해당 클래스를 인터페이스로 만든다. -> Account에서, ID타입으로 조회
//기본적으로 write를 안쓰고 읽기만 하게해서 메모리 사용량을 최적화
@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {
boolean existsByEmail(String email);
boolean existsByNickname(String nickname);
}
SignUpForm
package com.demo.account;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Length;
import lombok.Data;
@Data
public class SignUpForm {
//프론트엔드에서 검사를 하지만, 사용자가 어떤 방법으로 통과를 할경우를 대비해서 백엔드에서도 검사를 수행한다.
// 비어있지 않아야, 길이 설정, 정규식을 통해 패턴정의
@NotBlank
@Length(min = 3, max = 20)
@Pattern(regexp = "^[ㄱ-ㅎ가-힣a-z0-9_-]{3,20}$")
private String nickname;
@Email
@NotBlank
private String email;
@NotBlank
@Length(min = 8, max = 50)
private String password;
}
728x90
반응형
'Server Programming > Spring Boot Full-Stack Programming' 카테고리의 다른 글
[스프링 풀스택 클론 코딩]목업 테스트 mokito 이용하기 (0) | 2022.08.26 |
---|---|
[스프링 풀스택 클론 코딩 - 회원가입] (1-6) 회원가입 폼 서브밋 처리 (0) | 2022.08.26 |
[스프링 풀스택 클론 코딩] @Valid @Length 어노테이션 의존성 추가 (0) | 2022.08.26 |
[스프링 풀스택 클론 코딩 - 회원가입] (1-4) 회원가입 뷰 (0) | 2022.08.26 |
[스프링 풀스택 클론 코딩] 회원가입 페이지 만들기 (+ 부트스트랩, 자바스크립트, 롬복, 타임리프) (0) | 2022.08.26 |