본문 바로가기
JAVA

MimeMessage , Multipart , MimeBodyPart 를 이용한 HTML 메일 본문 , 이미지 , 첨부파일 전송 예제

by Hwoarang757 2023. 12. 17.

MimeMessage , Multipart , MimeBodyPart 를 이용한 HTML 메일 본문 , 이미지 , 첨부파일 전송 예제입니다.

 

package com.Test.doc.controller;

import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import jakarta.activation.DataHandler;
import jakarta.activation.DataSource;
import jakarta.activation.FileDataSource;
import jakarta.mail.Message.RecipientType;
import jakarta.mail.Multipart;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.MimeMultipart;
import jakarta.mail.util.ByteArrayDataSource;


@RestController
public class MailTestController {

    private final Logger logger = LogManager.getLogger(FileController.class);

    @Autowired
    private JavaMailSenderImpl mailSender;


    /*
    @Autowired
    private JavaMailSender javaMailSender;

    @Bean
    public JavaMailSenderImpl mailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

        return javaMailSender;
    }
    */


    @GetMapping("/MailSendTest")
    public String MailSendTest(@RequestParam HashMap<String,String> param) {
        String methodName = new Exception().getStackTrace()[0].getMethodName();

        logger.info(methodName);
        try {
            String from = "lionking7@Test.com";
            String to = "lionking7@Test.com";
            String subject = "SMTP 발송 테스트 진행";
            StringBuffer sb = new StringBuffer();

            sb.append("<html><head></head><body><p style='font-size:30px'>MIME Message 테스트</p>");
            sb.append("<img src='http://localhost:38080/img/400_500.jpg' />"); // 이미지 태그 포함 테스트 진행
            sb.append("<br />"); // 이미지 태그 포함 테스트 진행
            sb.append("<img src='http://localhost:38080/img/500_400.jpg' />"); // 이미지 태그 포함 테스트 진행
            sb.append("</body></html>");


            MimeMessage mimeMessage = mailSender.createMimeMessage();
            mimeMessage.setFrom(from);
            mimeMessage.setRecipient(RecipientType.TO, new InternetAddress(to));
            mimeMessage.setSubject(subject);

            Multipart multipart = new MimeMultipart();
            
            // HTML 의 이미지 처리 변경
            Document doc = Jsoup.parse(sb.toString());

            // 본문을 먼저 설정 해야 이미지가 첨부 됨 -_-; ) SetText를 먼저해야 함
            HashMap<String,String> imgUrlMap = new HashMap<>();
            int[] imgIdx = {0};

            doc.getElementsByTag("img").stream().forEach(a -> {
                String imgURL = a.attr("src");
                String imgCid = String.format("imgID%d" , imgIdx[0]);

                imgUrlMap.put(imgCid , imgURL);
                //img src 값 수정
                a.attr("src",String.format("cid:%s", imgCid));
                imgIdx[0]++;
            });

            MimeBodyPart htmlBodyPart = new MimeBodyPart();
            htmlBodyPart.setContent(doc.toString() , "text/html;charset=UTF-8");
            multipart.addBodyPart(htmlBodyPart);


            imgUrlMap.forEach((key,val) -> {
                try {
                    // 이미지 첨부 진행
                    CloseableHttpClient httpClient = HttpClients.createDefault();
                    HttpGet httpGet = new HttpGet(val);

                    CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
                    try(InputStream inputStream = httpResponse.getEntity().getContent();) {
                        DataSource dataSource = new ByteArrayDataSource(inputStream, "image/jpeg");

                        MimeBodyPart imagePart = new MimeBodyPart();
                        imagePart.setHeader("Content-ID", key );
                        imagePart.setDataHandler(new DataHandler(dataSource));
                        multipart.addBodyPart(imagePart);
                    }

                } catch(Exception exception) {
                    logger.error(methodName,exception);
                }
            });


            Arrays.asList(1,2).forEach(a -> {
                MimeBodyPart mimeBodyPart = new MimeBodyPart();
                try {

                    if(a == 1) {
                        FileDataSource fds = new FileDataSource(new File("D:/testf - 복사본 - 복사본.doc"));
                        mimeBodyPart.setDataHandler(new DataHandler(fds));
                        mimeBodyPart.setFileName("testf - 복사본 - 복사본.doc");
                    } else {
                        FileDataSource fds = new FileDataSource(new File("D:/testf - 복사본 - 복사본 (5)"));
                        mimeBodyPart.setDataHandler(new DataHandler(fds));
                        mimeBodyPart.setFileName("D:/testf - 복사본 - 복사본 (5)");
                    }
                    multipart.addBodyPart(mimeBodyPart);
                } catch(Exception exception) {
                    logger.error(methodName,exception);
                }
            });

            mimeMessage.setContent(multipart);


            /*
            ASIS MimeMessageHelper를 이용한 방식
            //mimeMessage = MDN.builder().build().asMimeMessage();
            MimeMessageHelper mimeHelper = new MimeMessageHelper(mimeMessage , true , "UTF-8");

            mimeHelper.setFrom(from);
            mimeHelper.setTo(to);
            mimeHelper.setSubject(subject);

            // HTML 의 이미지 처리 변경
            Document doc = Jsoup.parse(sb.toString());

            // 본문을 먼저 설정 해야 이미지가 첨부 됨 -_-; ) SetText를 먼저해야 함
            HashMap<String,String> imgUrlMap = new HashMap<>();
            int[] imgIdx = {0};

            doc.getElementsByTag("img").stream().forEach(a -> {
                String imgURL = a.attr("src");
                String imgCid = String.format("imgID%d" , imgIdx[0]);

                imgUrlMap.put(imgCid , imgURL);
                //img src 값 수정
                a.attr("src",String.format("cid:%s", imgCid));
                imgIdx[0]++;
            });

            // 본문 설정 처리 진행 ( img src 변경 )
            mimeHelper.setText(doc.toString() , true);

            imgUrlMap.forEach((key,val) -> {
                try {
                    // 이미지 첨부 진행
                    CloseableHttpClient httpClient = HttpClients.createDefault();
                    HttpGet httpGet = new HttpGet(val);

                    CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
                    try(InputStream inputStream = httpResponse.getEntity().getContent();) {
                        DataSource dataSource = new ByteArrayDataSource(inputStream, "image/jpeg");
                        mimeHelper.addInline(key , dataSource);
                    }

                } catch(Exception exception) {
                    logger.error(methodName,exception);
                }
            });
            */

            //logger.info(doc.toString());
            logger.info(mailSender.getHost());
            logger.info(mailSender.getPort());


            mailSender.send(mimeMessage);


        } catch(Exception exception) {
            logger.error(exception);
        }
        return "SUCCESS";
    }




}

 

수신 결과