Spring Boot 集成 Email、Velocity 多線程發送 郵件

郵件發送

郵件發送基本涉及到各種系統,是研發中必不可少的技能。一直連續做了好多次郵件發送,整理如下:

需要依賴

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <!-- velocity -->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity</artifactId>
        <version>1.7</version>
    </dependency>

項目結構如下在這裏插入圖片描述

##模板 :

 <div>
    <h1>
        <div>${message}</div>
    </h1>
</div>

配置文件

#spring.mail.host = smtphm.qiye.163.com
spring.mail.host = smtp.qiye.163.com
spring.mail.username = [email protected]
spring.mail.password = NksZVAePC2Rs6b6E
spring.mail.port = 465
spring.mail.properties.mail.smtp.auth = true
spring.mail.properties.mail.smtp.starttls.enable = true
spring.mail.properties.mail.smtp.starttls.required = true
spring.mail.properties.mail.smtp.timeout = 30000
spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.debug = false
spring.mail.default-encoding = UTF-8

實現代碼

多線程類

import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.internet.MimeMessage;

/**
 * @author li-jc
 * @version 1.0.0
 * @className MailTask
 * @description 線程類
 * @date 2019/12/5 14:24
 * @since JDK 1.8
 */
@Slf4j
public class MailTask implements Runnable {
    private String from;
    private String to;
    private String subject;
    private String content;
    private JavaMailSender sender;

    public MailTask(String from, String to, String subject, String content, JavaMailSender sender) {
        this.from = from;
        this.to = to;
        this.subject = subject;
        this.content = content;
        this.sender = sender;
    }

    @Override
    public void run() {
        log.info("send HTML mail thread begin");
        MimeMessage message = sender.createMimeMessage();

        try {
            //true表示需要創建一個multipart message
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            sender.send(message);
            log.info("send HTML mail thread end");
        } catch (Exception e) {
            log.error("send HTML mail thread exception!", e);
        }
    }
}

發送郵件線程池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author li-jc
 * @version 1.0.0
 * @className MailExecutorService
 * @description 發送郵件線程池
 * date: 2018/1/13 14:43 <br/>
 * @since JDK 1.8
 */
public class MailExecutorService {
    private volatile static ExecutorService executorService;

    public static ExecutorService getExecutorService(){
        if (executorService == null) {
            synchronized (MailExecutorService.class){
                if (executorService == null) {
                    executorService = Executors.newFixedThreadPool(20);
                }
            }
        }
        return  executorService;
    }
}

郵件服務

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.concurrent.ExecutorService;

/**
 * @author li-jc
 * @version 1.0.0
 * @className MailExecutorService
 * @description 發送郵件
 * date: 2018/1/12 14:43 <br/>
 * @since JDK 1.8
 */
@Slf4j
@Service
public class MailService {

    @Autowired
    private JavaMailSender sender;

    @Value("${spring.mail.username}")
    private String from;

    /**
     * 發送純文本的簡單郵件 
     * @param to
     * @param subject
     * @param content
     */
    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("城雲產品三部<"+ from +">");
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);

        try {
            sender.send(message);
            log.info("簡單郵件已經發送。");
        } catch (Exception e) {
            log.error("發送簡單郵件時發生異常!", e);
        }
    }

    /**
     * 發送html格式的郵件 
     * @param to
     * @param subject
     * @param content
     */
    public void sendHtmlMail(String to, String subject, String content){
        try {
            log.info("send HTML mail start");
            ExecutorService executorService = MailExecutorService.getExecutorService();
            executorService.execute(new MailTask("城雲產品三部<"+ from +">",to,subject,content,sender));
            log.info("send HTML mail end");
        } catch (Exception e) {
            log.error("send HTML mail exception", e);
        }
    }

    /**
     * 發送帶附件的郵件 
     * @param to
     * @param subject
     * @param content
     * @param filePath
     */
    public void sendAttachmentsMail(String to, String subject, String content, String filePath){
        MimeMessage message = sender.createMimeMessage();
        
        try {
            //true表示需要創建一個multipart message  
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom("城雲產品三部<"+ from +">");
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            FileSystemResource file = new FileSystemResource(new File(filePath));
            String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
            helper.addAttachment(fileName, file);

            sender.send(message);
            log.info("帶附件的郵件已經發送。");
        } catch (MessagingException e) {
            log.error("發送帶附件的郵件時發生異常!", e);
        }
    }

    /**
     * 發送嵌入靜態資源(一般是圖片)的郵件 
     * @param to
     * @param subject
     * @param content 郵件內容,
     *                需要包括一個靜態資源的id,比如:<img src=\"cid:rscId01\" >
     * @param rscPath 靜態資源路徑和文件名 
     * @param rscId 靜態資源id 
     */
    public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
        MimeMessage message = sender.createMimeMessage();

        try {
            //true表示需要創建一個multipart message  
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom("城雲產品三部<"+ from +">");
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource res = new FileSystemResource(new File(rscPath));
            helper.addInline(rscId, res);

            sender.send(message);
            log.info("嵌入靜態資源的郵件已經發送。");
        } catch (MessagingException e) {
            log.error("發送嵌入靜態資源的郵件時發生異常!", e);
        }
    }
}  

封裝郵件基礎服務

import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
import java.util.Properties;

/**
 * 基礎服務
 * Created by lijc on 2017-10-02
 */
@Slf4j
@Service
public class BaseService {

    @Resource
    private MailService mailService;

    @Resource
    private Environment environment;



    /** 發送測試郵件
     * eg :templatePath email/test.vm
     * */
    public boolean sendTestEmail(final String email,final  String message, final String templatePath ) {
        Properties p = new Properties();

        // 加載 classpath 目錄下的 vm 文件
        p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        p.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
        p.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
        p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");

        Velocity.init(p); // 初始化

        VelocityContext context = new VelocityContext();

        context.put("message", message);

        StringWriter writer = new StringWriter();
        Template template = Velocity.getTemplate(templatePath);

        template.merge(context, writer);

        String html = writer.toString();

        try {
            writer.close();
        } catch (IOException e) {
            log.error("Close StringWriter Exception: {}", e.getMessage());
        }

        mailService.sendHtmlMail(email, "【產品三部】測試郵件", html);

        return true;
    }

}

總結:完整的實現了郵件發送功能,採用了自定義模板、多線程發送。如有不妥之處希望留言。如果想方便每次都能直接用可以結合springboot-starter,做成集成的啓動類,能直接調用。

發佈了11 篇原創文章 · 獲贊 10 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章