[Spring] 이메일 전송 기능 구현하기

예원·2022년 8월 30일
0

Spring 글 모아보기

목록 보기
6/17

얼마전 제9회 SW개발보안경진대회(소개딩4)에 참여했다.
그때 주어진 현장미션에 대해 기록하려고 한다.


0. 현장미션

현장미션은 총 2가지가 있었고, 그 중 이메일 전송 기능을 개발하게 되었다.

버튼을 추가하여 현재 화면을 지정된 이메일로 발송하는 기능 구현

아래의 과정을 거쳐 미션을 해결하기로 했다.

  1. 앱에서 캡처 화면 및 로그인 사용자의 email을 서버()로 전송
  2. 서버에서 파일 저장
  3. 이메일 전송

1. 캡처 화면 저장

Email Controller를 생성해 앱에서 보내준 캡처화면과 이메일을 받는다.
그 후, 받아온 캡처 화면 이미지를 서버에 저장한다.

(혹시나 앱에서 화면 캡처 과정이 궁금하신 분들은 아래의 글에서 확인할 수 있다.)
🔽🔽🔽
[React Native] 버튼을 클릭하여 현재 화면을 캡처해보자❗

이미지 저장은 저번에 만든 File Service를 이용하였다.
🔽🔽🔽
File Upload : 게시판에 파일 첨부 기능 추가하기
File : 서버에 저장한 파일 외부경로 설정

EmailController 를 생성하여 /email 로 들어온 이미지를 저장한다.

@RestController
@RequestMapping("/email")
public class EmailController {

    @Autowired
    FileService fileService;

    @PostMapping(value = "", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    public ResponseEntity emailSend(MultipartHttpServletRequest request, @RequestParam(value = "file") MultipartFile file) throws MessagingException, IOException {

        if(file != null) {
            FileDTO filedto = fileService.uploadFile(file);

            if (filedto.getCode() == -2) {
                return new ResponseEntity(ResponseFmt.res(StatusCode.BAD_REQUEST, ResponseMessage.IMAGE_UPLOAD_ERROR), HttpStatus.OK);
            }
            if (filedto.getCode() == -1) {
                return new ResponseEntity(ResponseFmt.res(StatusCode.BAD_REQUEST, ResponseMessage.CANT_NOT_OTHER_FILES), HttpStatus.OK);
            }

            // 메일 전송
        }

        return new ResponseEntity(ResponseFmt.res(StatusCode.OK, ResponseMessage.SEND_EMAIL_SUCCESS), HttpStatus.OK);
    }

}

2. Email 전송 준비

Email을 전송하기 위한 설정 및 DTO, Service를 생성한다.

2-1. gmail 설정

계정 설정 > 보안에서 2단계 인증을 설정하고 앱 비밀번호를 생성한다.
계정설정

Gmail > 설정 > 전달 및 POP/IMAP 에서 POP과 IMAP을 사용으로 변경한다.
이메일 설정

2-2. application.properties

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=계정@gmail.com
spring.mail.password=생성한 앱 비밀번호
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

2-3. MailDTO

Mail DTO는 간단하게 받는사람 주소, 제목, 내용으로 구성하였다.

@Getter
@Setter
@NoArgsConstructor
public class MailDTO {
    private String email;
    private String title;
    private String content;

    @Builder
    public MailDTO(final String email, String title, String content){
        this.email = email;
        this.title = title;
        this.content = content;
    }
}

2-4. EmailService

Email Service를 이용해 이메일을 전송한다.

@Service
public class EmailService {

    @Autowired
    private JavaMailSender javaMailSender;

	// 첨부파일이 저장된 위치
    @Value("${imageFile.uploadPath}")
    private String filePath;

	// 보내는 사람 주소
    private String fromMail = "계정@gmail.com";

	// 메일 정보가 담김 MailDTO와 파일 정보가 담긴 FileDTO를 파라미터로 받음
    public void sendMail(MailDTO mailDTO, FileDTO file) {

        try {
        	// 메시지 생성
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            // 받는사람, 보내는사람, 제목, 내용을 입력
            helper.setTo(mailDTO.getEmail());
            helper.setFrom(fromMail, "관리자");	//주소, 별칭
            helper.setSubject(mailDTO.getTitle());
            helper.setText(mailDTO.getContent(), true);

			// 이미지 파일 첨부
            FileSystemResource fileImg = new FileSystemResource(new File(filePath + file.getFilepath()));
            helper.addAttachment(file.getFilename(), fileImg);
            
            // 메일 전송
            javaMailSender.send(message);

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}

3. 메일 전송

Email Service를 사용하여 캡처화면 저장 후 메일을 전송한다.

@RestController
@RequestMapping("/email")
public class EmailController {

    ...

    @Autowired
    EmailService emailService;

    @PostMapping(value = "", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
    public ResponseEntity emailSend(MultipartHttpServletRequest request, @RequestParam(value = "file") MultipartFile file) throws MessagingException, IOException {

        if(file != null) {
            FileDTO filedto = fileService.uploadFile(file);

            ...

			// 파일 저장 후, 메일 전송을 위한 DTO를 생성
            MailDTO mail = MailDTO.builder()
                    .email(request.getParameter("email"))
                    .title("제목 입력")
                    .content("내용 입력")
                    .build();

			// 메일 전송
            emailService.sendMail(mail, filedto);
        }

        return new ResponseEntity(ResponseFmt.res(StatusCode.OK, ResponseMessage.SEND_EMAIL_SUCCESS), HttpStatus.OK);
    }

}

4. 결과

앱에서 화면 전송 버튼을 클릭하면 캡처 화면이 메일로 전송되는 것을 확인할 수 있다.

메일 전송 결과

0개의 댓글