[Practice] 메일 전송 (3)

2021. 4. 20. 15:52Spring/Practice

1. 문제

  • 게시판에 글을 작성했을 때 사용자에게 작성된 글의 정보를 메일로 전송하는 API

 

 

 

2. 풀이

- data.sql

INSERT INTO MAIL_TEMPLATE(ID, TEMPLATE_ID, TITLE, CONTENTS, SEND_EMAIL, SEND_USER_NAME, REG_DATE) VALUES
    (1, 'USER_RESET_PASSWORD', '{USER_NAME}님의 비밀번호 초기화 요청입니다.', '<div><p>{USER_NAME}님 안녕하세요.</p><p>아래 링크를 클릭하여, 비밀번호를 초기화해주세요.</p><p><a href="{SERVER_URL}/reset?key={RESET_PASSWORD_KEY}">초기화</a></p></div>',
    'ozofweird@gmail.com', '관리자', '2021-01-01 01:01:01.000000'),
    (2, 'BOARD_ADD', '{USER_NAME}님이 글을 게시하였습니다.', '<div><p>제목: {BOARD_TITLE}</p><p>내용</p><div>{BOARD_CONTENTS}</div></div>',
    'ozofweird@gmail.com', '관리자', '2021-01-01 01:01:01.000000');

- BoardService.java

package com.example.jpa.sample.board.service;

import com.example.jpa.sample.board.entity.Board;
import com.example.jpa.sample.board.entity.BoardBadReport;
import com.example.jpa.sample.board.entity.BoardComment;
import com.example.jpa.sample.board.entity.BoardType;
import com.example.jpa.sample.board.model.*;

import java.util.List;

public interface BoardService {

    ...

    ServiceResult add(String email, BoardInput boardInput);
}

- BoardServiceImpl.java

package com.example.jpa.sample.board.service;

import com.example.jpa.sample.board.entity.*;
import com.example.jpa.sample.board.model.*;
import com.example.jpa.sample.board.repository.*;
import com.example.jpa.sample.common.MailComponent;
import com.example.jpa.sample.common.exception.BizException;
import com.example.jpa.sample.mail.entity.MailTemplate;
import com.example.jpa.sample.mail.repository.MailTemplateRepository;
import com.example.jpa.sample.user.entity.User;
import com.example.jpa.sample.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@RequiredArgsConstructor
@Service
public class BoardServiceImpl implements BoardService {

    private final BoardTypeRepository boardTypeRepository;
    private final BoardRepository boardRepository;
    private final BoardTypeCustomRepository boardTypeCustomRepository;
    private final BoardHitsRepository boardHitsRepository;
    private final BoardLikeRepository boardLikeRepository;
    private final BoardBadReportRepository boardBadReportRepository;
    private final BoardScrapRepository boardScrapRepository;
    private final BoardBookmarkRepository boardBookmarkRepository;
    private final BoardCommentsRepository boardCommentsRepository;

    private final UserRepository userRepository;

    private final MailTemplateRepository mailTemplateRepository;
    private final MailComponent mailComponent;

    ...

    @Override
    public ServiceResult add(String email, BoardInput boardInput) {
        Optional<User> optionalUser = userRepository.findByEmail(email);
        if(!optionalUser.isPresent()) {
            throw new BizException("회원 정보가 존재하지 않습니다.");
        }
        User user = optionalUser.get();

        Optional<BoardType> optionalBoardType = boardTypeRepository.findById(boardInput.getBoardType());
        if(!optionalBoardType.isPresent()) {
            return ServiceResult.fail("게시판 정보가 존재하지 않습니다.");
        }
        BoardType boardType = optionalBoardType.get();

        Board board = Board.builder()
                .user(user)
                .boardType(boardType)
                .title(boardInput.getTitle())
                .contents(boardInput.getContents())
                .regDate(LocalDateTime.now())
                .build();

        boardRepository.save(board);

        // 메일 전송 로직
        Optional<MailTemplate> optionalMailTemplate = mailTemplateRepository.findByTemplateId("BOARD_ADD");
        optionalMailTemplate.ifPresent((e) -> {

            String fromEmail = e.getSendEmail();
            String fromName = e.getSendUserName();

            String title = e.getTitle().replaceAll("\\{USER_NAME\\}", user.getName());
            String contents = e.getContents().replaceAll("\\{BOARD_TITLE\\}", board.getTitle())
                    .replaceAll("\\{BOARD_CONTENTS\\}", board.getContents());

            mailComponent.send(fromEmail, fromName, user.getEmail(), user.getName(), title, contents);
        });

        return ServiceResult.success();
    }
}

- board_add.html (resource - mail-template)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{USER_NAME}님이 글을 게시하였습니다.</title>
</head>
<body>
    <div>
        <p>제목: {BOARD_TITLE}</p>
        <p>내용</p>
        <div>
            {BOARD_CONTENTS}
        </div>
    </div>

</body>
</html>

- ApiBoardController.java

package com.example.jpa.sample.board.controller;

import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.jpa.sample.board.entity.Board;
import com.example.jpa.sample.board.entity.BoardType;
import com.example.jpa.sample.board.model.*;
import com.example.jpa.sample.board.service.BoardService;
import com.example.jpa.sample.common.exception.BizException;
import com.example.jpa.sample.common.model.ResponseResult;
import com.example.jpa.sample.notice.model.ResponseError;
import com.example.jpa.sample.user.model.ResponseMessage;
import com.example.jpa.sample.util.JwtUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RequiredArgsConstructor
@RestController
public class ApiBoardController {

    private final BoardService boardService;

    ...

    //------------------------------------------------------------------------------
    // 문제 3
    @PostMapping("/api/board")
    public ResponseEntity<?> add(@RequestBody BoardInput boardInput, @RequestHeader("X-ACCESS-TOKEN") String token) {

        String email = JwtUtils.getIssuer(token); // 인터셉터에서 자동으로 예외를 잡음
        ServiceResult result = boardService.add(email, boardInput);

        return ResponseResult.success(result);
    }
}
728x90

'Spring > Practice' 카테고리의 다른 글

[Practice] 스케쥴러 활용 (1)  (0) 2021.04.20
[Practice] 메일 전송 (4)  (0) 2021.04.20
[Practice] 메일 전송 (2)  (0) 2021.04.20
[Practice] 메일 전송 (1)  (0) 2021.04.20