@Controller
@RequiredArgsConstructor
public class AccountController {
private final SignUpFormValidator signUpFormValidator;
private final AccountRepository accountRepository;
private final ConsoleMailSender javaMailSender;
@InitBinder("signUpForm")
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.addValidators(signUpFormValidator);
}
@GetMapping("/sign-up")
public String signUp(Model model) {
model.addAttribute(new SignUpForm());
return "account/sign-up";
}
@PostMapping("/sign-up")
public String signUpSubmit(@Valid SignUpForm signUpForm, Errors errors) {
if (errors.hasErrors()) {
return "account/sign-up";
}
Account account = Account.builder()
.email(signUpForm.getEmail())
.nickname(signUpForm.getNickname())
.password(signUpForm.getPassword()) // TODO encoding 해야함
.studyCreatedByWeb(true)
.studyEnrollmentResultByWeb(true)
.studyUpdatedByWeb(true)
.build();
Account newAccount = accountRepository.save(account);
newAccount.generateEmailCheckToken();
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(newAccount.getEmail());
mailMessage.setSubject("스터디올래, 회원 가입 인증");
mailMessage.setText("/check-email-token?token="+ newAccount.getEmailCheckToken() +
"&email=" + newAccount.getEmail());
javaMailSender.send(mailMessage);
return "redirect:/";
}
}
@PostMapping /sign-up으로 form submit 전송에대한 Validate를 실행합니다.
SignUpForm같은 객체로 받을 경우 @ModelAttribute를 사용해야하지만 기본적으로 생략해도 됩니다.
@Valid 어노테이션으로 Validate를 진행합니다.
@Data
public class SignUpForm {
@NotBlank
@Length(min = 3, max = 20)
@Pattern(regexp = "^[ㄱ-ㅎ가-힣a-zA-Z\\d_-]{3,20}$")
private String nickname;
@Email
@NotBlank
private String email;
@NotBlank
@Length(min = 8, max = 50)
private String password;
}
@Valid 어노테이션시의 로직을 실행할 어노테이션입니다. 각각의 요소는 비어있으면 안되기 때문에 @NotBlank를 사용합니다.
비슷한 어노테이션으로 @NotNull과 @NotEmpty가 있습니다.
@NotNull의 경우 말 그대로 null만 제외하고 @NotEmpty의 경우 null, ""을 제외합니다. 그치만 " "와 같은 띄어쓰기는 허용합니다.
@NotBlank는 null, "", " " 모두 제외시킵니다.
SignUpForm에 들어가는 nickname, email, password 셋 모두 빈칸도 허용할 수 없으므로 @NotBlank를 사용합니다.
@Length의 경우 길이, @Pattern(regexp = "")는 정규식으로 패턴을 정규화하는 것입니다. @Email을 email의 형식인지를 Validate하는 어노테이션입니다.
@Component
@RequiredArgsConstructor
public class SignUpFormValidator implements Validator {
private final AccountRepository accountRepository;
@Override
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(SignUpForm.class);
}
@Override
public void validate(Object target, Errors errors) {
SignUpForm signUpForm = (SignUpForm) target;
if (accountRepository.existsByEmail(signUpForm.getEmail())) {
errors.rejectValue("email", "invalid.email", new Object[]{signUpForm.getEmail()}, "이미 사용중인 이메일입니다.");
}
if (accountRepository.existsByNickname(signUpForm.getNickname())) {
errors.rejectValue("nickname", "invalid.nickname", new Object[]{signUpForm.getNickname()}, "이미 사용중인 닉네임입니다.");
}
}
}
AccountController에 주입된 SignUpFormValidator의 경우 springframework에서 제공하는 Validator객체를 implements해 사용합니다.
supports(Class<?> clazz), validate(Object target, Errors errors)을 Override해서 사용합니다.
'spring' 카테고리의 다른 글
WebSecurityConfigurerAdapter is deprecated (2) | 2022.08.03 |
---|---|
[JPA] table, entity 만들고 테스트하기 (0) | 2022.02.19 |
[Spring Boot] XCAPE Hint Project (0) | 2021.06.21 |
[스프링 프로젝트] 인스타그램 - 데이터베이스 (MySQL) (1) | 2021.05.04 |
[스프링 프로젝트] 인스타그램 - 첫 페이지와 회원가입 페이지 (0) | 2021.05.04 |