Java整合Spring發送郵件

我的博客項目地址html

但願各位幫忙點個star,給我加個小星星✨java


又懶了,要多看書和總結,而後早點寫博客😝

有時候代碼執行完以後,須要郵件進行通知,因此經過工做中的項目和網上的資料,特意去學習瞭如何使用Java發送郵件。Demo使用的是QQ郵箱進行郵件發送,能夠先了解一下基礎文檔協議RFC88二、MIME、SMTP等git


文檔協議說明

看了孤傲蒼狼的文章,關於郵件協議,他解釋的很好,這邊進行記錄了一下github

RFC882文檔(發送簡單文字郵件)

RFC882文檔規定了如何編寫一封簡單的郵件(純文本郵件),一封簡單的郵件包含郵件頭和郵件體兩個部分,郵件頭和郵件體之間使用空行分隔。spring

郵件頭包含的內容有:apache

  • from字段   --用於指明發件人
  • to字段    --用於指明收件人
  • subject字段 --用於說明郵件主題
  • cc字段    -- 抄送,將郵件發送給收件人的同時抄送給另外一個收件人,收件人能夠看到郵件抄送給了誰
  • bcc字段    -- 密送,將郵件發送給收件人的同時將郵件祕密發送給另外一個收件人,收件人沒法看到郵件密送給了誰

MIME文檔(能夠發送HTML郵件)

在咱們的實際開發當中,一封郵件既可能包含圖片,又可能包含有附件,在這樣的狀況下,RFC882文檔規定的郵件格式就沒法知足要求了。編程

MIME協議是對RFC822文檔的升級和補充,它描述瞭如何生產一封複雜的郵件。一般咱們把MIME協議描述的郵件稱之爲MIME郵件。MIME協議描述的數據稱之爲MIME消息。    對於一封複雜郵件,若是包含了多個不一樣的數據,MIME協議規定了要使用分隔線對多段數據進行分隔,並使用Content-Type頭字段對數據的類型、以及多個數據之間的關係進行描述。   ide

SMTP協議

要使用QQ郵箱發送郵件,就要遵照SMTP協議。SMTP(Simple Mail Transfer Protocol)即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。工具

須要在QQ郵箱中打開SMTP服務和生成受權碼學習

QQ郵箱


Demo的時序圖


代碼實現

demo使用的是Velocity模板引擎進行html渲染,其它渲染方式相似,最後都是生成context內容。

基礎依賴

java mail/spring-context-support/velocity

compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.1'
compile group: 'org.springframework', name: 'spring-context-support', version: '5.0.8.RELEASE'
compile group: 'org.apache.velocity', name: 'velocity', version: '1.7'
複製代碼

郵件基礎Bean

public class MailBean {
    /** 郵件發送人地址,非空 */
    private String from;
    /** 郵件發送人姓名,非空 */
    private String fromName;
    /** 郵件接收人地址列表,非空 */
    private String[] toList;
    /** 郵件抄送人地址列表 */
    private String[] ccList;
    /** 郵件主題,非空 */
    private String subject;
    /** 郵件內容velocity上下文參數 */
    private Map<String, Object> mailContext;
    /** 郵件內容velocity模板,非空 */
    private String mailVmName;
    ···
}
複製代碼

模板引擎渲染工具

public class VelocityUtils {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(VelocityUtils.class);
    private static final VelocityEngine VE = new VelocityEngine();
    static {
        initVelocity();
    }
    private static void initVelocity() {
        try {
            VE.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
            VE.setProperty(
                    "classpath.resource.loader.class",
                    ClasspathResourceLoader.class.getName());
            VE.setProperty(RuntimeConstants.RUNTIME_LOG, "logs/velocity.log");
            VE.setProperty(
                    RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
                    "org.apache.velocity.runtime.log.NullLogChute");
            VE.init();
        } catch (Exception e) {
            LOGGER.warn("初始化velocity模板引擎失敗", e);
        }
    }
    /** 實際渲染的代碼,map裏面的字段與編寫的模板相對應 **/
    public static String render(String vmName, Map<String, Object> context) {
        String renderStr = "";
        try {
            Template template = VE.getTemplate(vmName, "UTF-8");
            VelocityContext velocityContext = new VelocityContext();
            for (Map.Entry<String, Object> entry : context.entrySet()) {
                velocityContext.put(entry.getKey(), entry.getValue());
            }
            StringWriter sw = new StringWriter();
            template.merge(velocityContext, sw);
            renderStr = sw.toString();
        } catch (Exception e) {
            LOGGER.warn("渲染vm模板失敗", e);
        }
        return renderStr;
    }
}
複製代碼

發送郵件的服務

咱們使用spring進行依賴注入,幫咱們託管mailSender

<bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <!-- <property name="host" value="smtp.qq.com"/> -->
        <property name="host" value="smtp.qq.com"/>
        <property name="port" value="587"/>
        <!-- <property name="username" value="xxxxx@qq.com"/> -->
        <property name="username" value="xxxxxx@qq.com"/>
        <!-- qq郵箱的受權碼,若是是企業郵箱,則使用登陸密碼 -->
        <property name="password" value="xxxxxxxxxxx"/>
        <property name="javaMailProperties">
            <props >
                <prop key="mail.smtp.auth">true</prop>
            </props>
        </property>
    </bean>
複製代碼

面向接口編程

public interface MailService {

    /** * 發送郵件 * * @param mailBean 郵件bean */
    void sendMail(MailBean mailBean);

}


@Service
public class MailServiceImpl implements MailService {

    @Autowired
    @Qualifier("javaMailSender")
    private JavaMailSender mailSender;


    @Override
    public void sendMail(MailBean mailBean) {
        // 省略了校驗
        try {
            // 工具類進行內容渲染,傳入的是模板名稱和具體內容MAP
            String mailContent = VelocityUtils.render(
                    mailBean.getMailVmName(),
                    mailBean.getMailContext());
            MimeMessage msg = mailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(msg, true, "UTF-8");
            mimeMessageHelper.setFrom(mailBean.getFrom(), mailBean.getFromName());
            mimeMessageHelper.setSubject(mailBean.getSubject());
            mimeMessageHelper.setTo(mailBean.getToList());
            mimeMessageHelper.setText(mailContent, true);

            mailSender.send(msg);

        } catch (Exception e) {
            log.warn("郵件發送失敗,mailBean={}", mailBean, e);
        }
    }
}
複製代碼

demo.vm(模板文件)

<html xmlns="http://www.w3.org/1999/xhtml ">
<body class="word-style">
<div class="title" align="center">DEMO</div>
<br/>
<div class="indent">$!{msg}</div>
</body>
</html>
複製代碼

發送郵件

最後經過調用MailService進行郵件發送

MailBean mailBean = new MailBean();
mailBean.setFrom("xxxxxx@qq.com");
mailBean.setFromName("DEMO");
mailBean.setSubject("Are you ok");
//模板
mailBean.setMailVmName("demo.vm");
//收件人地址
String[] toList = {"xxxxx@xxxx.com"};
mailBean.setToList(toList);
Map<String, Object> context = new HashMap<>();
context.put("msg", "I'm fine, thank you~");
mailBean.setMailContext(context);
mailService.sendMail(mailBean);
複製代碼

固然,你能夠製做更加好看的html郵件~


參考資料

  1. JavaWeb學習總結(五十二)——使用JavaMail建立郵件和發送郵件
  2. Java 發送郵件
  3. 經過spring實現javamail發送郵件功能
  4. 騰訊的IMAP服務說明
相關文章
相關標籤/搜索