프로젝트 정리/스프링과 JPA 기반 웹 애플리케이션 개발

6 - 2 . 회원 가입 폼 서브밋 처리

출처 : www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1/dashboard

 

스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런

이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습

www.inflearn.com

 

 

 

Spring-boot-starter-mail

MailSenderAutoConfiguration 에서 MailSender 주입 받아 만들수도 있지만 임의 클래스 생성

콘솔에 출력하는 ConsoleMailSender

 

package com.studyolle.account;

import lombok.extern.slf4j.Slf4j;
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 javax.mail.internet.MimeMessage;
import java.io.InputStream;

@Profile("local")
@Component
@Slf4j      //lombok annotation
public class ConsoleMailSender implements JavaMailSender {
    //JavaMailSender를 상속받은 가짜 객체를 bean으로 등록해서 사용

    @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 {

    }
}

 

 

 

package com.studyolle.account;

import com.studyolle.domain.Account;
import lombok.RequiredArgsConstructor;
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 javax.validation.Valid;


@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);

        // signUpForm데이터를 받을 때 타입의 camelCase이름을 따라감
        // @Valid SignUpForm signUpForm(mapping)

        /*
        signUpSubmit에
        validate 검증을 한번 더 하는 것을 InitBinder로
        signUpSubmit에들어 왔을때 validate 검사를 하고
        signUpFormValidator.validate(signUpForm, errors);
        if(errors.hasErrors());
            return "account/sign-up";
        }
        */
    }

    @GetMapping("/sign-up")
    public String signUpForm(Model model) {
        model.addAttribute(new SignUpForm()); // 객체 attribute의 이름이 된다.
        // camel Case 값 -> "signUpForm"문자열이 들어감
        return "account/sign-up";
    }

    @PostMapping("/sign-up")
    public String signUpSubmit(@Valid SignUpForm signUpForm, Errors errors) {
        // 복합 객체 ( 여러 값) -> ModelAttribute로 받아오는데 파라미터로 쓰일때 생략이 가능하다.
        // Data를 컨버젼하거나 binding할때 발생할 수 있는 에러를 받아주는 타입 -> Erros
        if(errors.hasErrors()){
            //SignUpForm JSR 303 Annotation에 정의한 값에 걸리면
            // Binding Errors errors에 담기고 에러가 있다고 조건문에 걸려서 form으로 돌아감
            return "account/sign-up";
        }

        Account account = Account.builder()
                .email(signUpForm.getEmail())
                .nickname(signUpForm.getNickname())
                .password(signUpForm.getPassword()) // TODO encoding 해야 함 (hash로 바꿔서)
                .studyCreateByWeb(true)
                .studyEnrollmentResultByWeb(true)
                .studyUpdateByWeb(true)
                .build();
        Account newAccount = accountRepository.save(account);


        newAccount.generateEmailCheckToken(); //UUID
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        //Subject -> 제목 설정 | setText -> 본문설정
        mailMessage.setTo(newAccount.getEmail());
        mailMessage.setSubject("스터디올래, 회원 가입 인증");
        mailMessage.setText("/check-email-token?token=" +
                newAccount.getEmailCheckToken() + "&email=" + newAccount.getEmail());

        javaMailSender.send(mailMessage);
        return "redirect:/";

    }
}

@postMapping으로 가입 값이 오면

if에서 유효성 검사

Validation으로 @NotBlank, @Length, @Pattern등) 및 중복검사

WebDataBinder로 SignUpFormValidator내부의 existsByEmail, existsByNickname을 활용

유효성 검증이 끝난 값이면 Account 객체를 Build로 채우고 생성

UUID로 EmailToken생성

제목 및 본문을 생성하고 slf4j로 log찍어서 확인