회원 가입 폼 검증
- JSR 303 애노테이션 검증
- 값의 길이, 필수 값
- 커스텀 검증
- 중복이메일, 닉네임 여부 확인
- 폼 에러 있을 시, 폼 다시 보여주기
회원 가입 처리
- 회원 정보 저장
- 인증 이메일 발송
- 처리 후 첫 페이지로 리다이렉트 (Post-Redirect-Get 패턴)
회원가입 정보를 전달할 SignUpForm 생성(여기서 JSR 303 애노테이션 검증)
package me.weekbelt.studyolle.account;
@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;
}
커스텀 검증(중복이메일, 닉네임 여부 확인)을 위해 Validator를 상속받는 SignUpFormValidator 작성
package me.weekbelt.studyolle.account;
@RequiredArgsConstructor
@Component
public class SignUpFormValidator implements Validator {
private final AccountRepository accountRepository;
// 어떠한 도메인 클래스에 대한 검증인지 설정
@Override
public boolean supports(Class<?> aClass) {
return aClass.isAssignableFrom(SignUpForm.class);
}
@Override
public void validate(Object object, Errors errors) {
SignUpForm signUpForm = (SignUpForm) object;
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()}, "이미 사용중인 닉네임 입니다.");
}
}
}
AccountRepository 작성
package me.weekbelt.studyolle.account;
@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {
boolean existsByEmail(String email);
boolean existsByNickname(String nickname);
}
AccountController에 유효성 검증과 회원 저장을 위한 회원가입 POST 요청 추가
package me.weekbelt.studyolle.account;
@RequiredArgsConstructor
@Controller
public class AccountController {
private final SignUpFormValidator signUpFormValidator;
private final AccountRepository accountRepository;
@InitBinder("signUpForm")
public void initBinder(WebDataBinder webDataBinder){
webDataBinder.addValidators(signUpFormValidator);
}
@GetMapping("/sign-up")
public String signUpForm(Model model){
model.addAttribute("signUpForm", 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 해야함
.emailVerified(false)
.studyEnrollmentResultByWeb(true)
.studyUpdatedByWeb(true)
.build();
return "redirect:/";
}
}
이메일 전송을 위해 ConsoleMailSender 작성(일단은 콘솔로 보내서 메시지가 제대로 전달되는지만 확인)
package me.weekbelt.studyolle.mail;
@Slf4j
@Profile("local")
@Component
public class ConsoleMailSender implements JavaMailSender {
@Override
public MimeMessage createMimeMessage() {
return null;
}
@Override
public MimeMessage createMimeMessage(InputStream inputStream) throws MailException {
return null;
}
@Override
public void send(MimeMessage mimeMessage) throws MailException {
}
@Override
public void send(MimeMessage... mimeMessages) throws MailException {
}
@Override
public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
}
@Override
public void send(MimeMessagePreparator... mimeMessagePreparators) throws MailException {
}
@Override
public void send(SimpleMailMessage simpleMailMessage) throws MailException {
// 회원가입을 요청하면 출력
log.info(simpleMailMessage.getText());
}
@Override
public void send(SimpleMailMessage... simpleMailMessages) throws MailException {
}
}
Test용과 application.preperties를 분리 시키기 위해 application.properties 설정
spring.profiles.active=local
AccountController에 메일 관련 코드 추가
package me.weekbelt.studyolle.account;
@RequiredArgsConstructor
@Controller
public class AccountController {
// 기존코드...
private final JavaMailSender javaMailSender;
@PostMapping("/sign-up")
public String signUpSubmit(@Valid SignUpForm signUpForm, Errors errors){
// 기존코드…..
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:/";
}
}
참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#
스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런
이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습니다. 이 강좌를 충분히 학습한다면 여러분 만의 웹 서비스를 만들거나 취직에 도움이 될만한 포트폴리오를 만들 수 있을 겁니다. 활용 웹 개발 프레임워크 및 라이브러리 Java Spring Spring Boot Spring Data JPA Thymeleaf 온라인 강의 스
www.inflearn.com
'스프링과 JPA 기반 웹 어플리케이션 개발 > 1부 (개발환경, 회원가입, 로그인, 계정설정)' 카테고리의 다른 글
07. 회원 가입: 패스워드 인코더 (0) | 2020.04.18 |
---|---|
06. 회원 가입: 리팩토링 및 테스트 (0) | 2020.04.17 |
04. 회원가입 뷰 (0) | 2020.04.17 |
03. 회원 가입: 컨트롤러 (0) | 2020.04.17 |
02. Account 도메인 클래스 (0) | 2020.04.17 |