본문 바로가기

Server Programming/Spring Boot Full-Stack Programming

[스프링 풀스택 클론 코딩 - 회원가입] (1-6) 회원가입 폼 서브밋 처리

반응형

AccountController

package com.demo.account;

import javax.validation.Valid;

import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
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 com.demo.domain.Account;

import lombok.RequiredArgsConstructor;

@Controller
@RequiredArgsConstructor
public class AccountController {

	private final SignUpFormValidator signUpFormValidator;
	private final AccountRepository accountRepository;
	// 이메일 발송 관련 빈 의존성 주입
	private final JavaMailSender javaMailSender;

	@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 검증을 한다.

		// form을 이용해 account에 저장
		Account account = Account.builder().email(signUpForm.getEmail()).nickname(signUpForm.getNickname())
				.password(signUpForm.getPassword()) // TODO encoding (해시 암호화) 필요함
				// .emailVerified(false) //검증은 아직 이루어지지 않았으므로 null이 들어가 있어서 불필요
				.studyCreatedByWeb(true).studyEnrollmentResultByWeb(true).studyUpdatedByWeb(true)
				// 웹으로 알림을 알리는 옵션은 켜둔 상태로 저장 -> 나머지 기본값들은 모두 false
				.build();

		// 해당 account 생성 -> repository에 저장
		Account newAccount = accountRepository.save(account);
		// 회원가입 이메일 발송 -> starter-mail 이용 -> mailsender // 일단 가짜 객체에 저장해 콘솔에 출력

		// 계정인증을 위한 토큰값 생성 -> 유효 아이디를 이용해 랜덤 생성
		newAccount.generateEmailCheckToken();

		// 관련 객체 정의 후 -> 빈 정의 후 발송
		SimpleMailMessage mailMessage = new SimpleMailMessage();

		// 받는 주소
		mailMessage.setTo(newAccount.getEmail());
		// 제목 작성
		mailMessage.setSubject("Demo, 회원 가입 인증");
		// 본문 작성 -> 가입인증 링크 만들어 제공 -> 토큰값을 생성해 가입인증 진행
		mailMessage.setText(
				"/check-email-token?token=" + newAccount.getEmailCheckToken() + " &email=" + newAccount.getEmail());
		// 메일 발송 ->
		javaMailSender.send(mailMessage);

		// TODO 회원 가입 처리 valid에 안걸리면 회원가입
		return "redirect:/";

	}

}

 

 

ConsoleMailSender

package com.demo;

import java.io.InputStream;

import javax.mail.internet.MimeMessage;

import org.springframework.context.annotation.Profile;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

//가짜 객체를 빈으로 등록해 사용 -> properties에 spring.profiles.active==local 설정 필요 ->
@Profile("local")
@Component

//로깅하는데 사용하는 롬복 어노테이션
@Slf4j
public class ConsoleMailSender implements JavaMailSender{

	@Override
	public void send(SimpleMailMessage simpleMessage) throws MailException {
		// TODO Auto-generated method stub
		log.info(simpleMessage.getText());

	}

	@Override
	public void send(SimpleMailMessage... simpleMessages) throws MailException {
		// TODO Auto-generated method stub

	}

	@Override
	public MimeMessage createMimeMessage() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public MimeMessage createMimeMessage(InputStream contentStream) throws MailException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void send(MimeMessage mimeMessage) throws MailException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void send(MimeMessage... mimeMessages) throws MailException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
		// TODO Auto-generated method stub
	}

	@Override
	public void send(MimeMessagePreparator... mimeMessagePreparators) throws MailException {
		// TODO Auto-generated method stub
		
	}

}

 

Account

package com.demo.domain;

import java.time.LocalDateTime;
import java.util.UUID;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

//도메인 생성을 위한 어노테이션
@Entity

// id만 이용해, equals확인 -> equals 메서드 오버라이딩
@Getter @Setter @EqualsAndHashCode(of = "id")

//기본 생성자가 필요한 상태에서 @Builder사용하기 위해 
@Builder @AllArgsConstructor @NoArgsConstructor
public class Account {

	// 기본키와 생성 전략
	@Id	@GeneratedValue
	private Long id;
	
	
	//로그인 방식에서 이메일과 닉네임을 이용한 방식 지원하기 위해
	@Column(unique =true) //중복 방지
	private String email;
	@Column(unique =true)
	private String nickname;
	
	private String password;
	
	//이메일 인증 관련 참거짓판단
	private boolean emailVerified;

	//이메일 검증 토큰 값
	private String emailCheckToken;
	
	//회원가입날짜 변수
	private LocalDateTime joinedAt;
	
	private String bio;
	
	private String url;
	
	private String occpation;
	
	private String location;
	
	//이미지파일은 varchar 데이터형식보다 크기가 커서 사용하는 어노테이션
	//로딩 시간을 설정하는 어노테이션 즉시 로딩과 지연 로딩이 존재
	//즉시 로딩 EAGER, 지연 로딩 LAZY
	@Lob @Basic(fetch = FetchType.EAGER)
	private String profileImage;
	
	//생성, 가입, 갱신정보 알림 설정 -> Email, Web, 둘다
	private boolean studyCreatedByEmail;
	
	private boolean studyCreatedByWeb;
	
	private boolean studyEnrollmentResultByEmail;
	
	private boolean studyEnrollmentResultByWeb;
	
	private boolean studyUpdatedByEmail;
	
	private boolean studyUpdatedByWeb;
	
	//이메일 인증 위한 토큰 랜덤 생성 
	public void generateEmailCheckToken() {
		this.emailCheckToken =UUID.randomUUID().toString();
	}
	
}
반응형