天天看點

使用smtp協定實作郵箱資訊發送

package com.yonyou.threatIntelligence.service.impl;
import com.sun.mail.util.MailSSLSocketFactory;
import com.yonyou.threatIntelligence.dao.EmailDOMapper;
import com.yonyou.threatIntelligence.entity.Email;
import com.yonyou.threatIntelligence.service.SendEmailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SendEmailServiceImpl implements SendEmailService {
    /**
     * smtp郵件伺服器 smtp.qq.com
     */
    @Value("${email.host}")
    private String emailHost;

    /**
     * 郵件發送協定 smtp
     */
    @Value("${email.protocol}")
    private String emailProtocol;
    /**
     * 是否需要身份認證
     */
    @Value("${smtp.auth}")
    private String smtpAuth;

    @Value("${email}")
    private String email;

    @Value("${authorization.code}")
    private String authorizationCode;

    @Resource
    private EmailDOMapper emailDOMapper;


    /**
     * 發送郵件
     */
    @Override
    public void sendEmail() throws GeneralSecurityException {
        // 設定郵件發送基本屬性
        // 擷取系統屬性
        Properties prop = new Properties();
        // 設定smtp伺服器主機
        prop.setProperty("mail.host", emailHost);
        // 設定郵件發送協定
        prop.setProperty("mail.transport.protocol", emailProtocol);
        // 設定是否需要身份認證
        prop.setProperty("mail.smtp.auth", smtpAuth);
        // 關于QQ郵箱,還要設定SSL加密,加上以下代碼即可
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        prop.put("mail.smtp.ssl.enable", "true");
        prop.put("mail.smtp.ssl.socketFactory", sf);
        // 建立session執行個體對象
        Session session = Session.getInstance(prop, new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() {
                //發件人郵件使用者名、授權碼
                return new PasswordAuthentication(email, authorizationCode);
            }
        });
        // 啟用調試模式,這樣就可以檢視到程式發送email的運作狀态
        session.setDebug(true);
        try{
            // 擷取transport執行個體對象
            Transport ts = session.getTransport("smtp");
            // 打開連接配接
//            ts.connect(email, authorizationCode);
            ts.connect();
            // 建立消息
            Message message = createEmail(session);
            ts.sendMessage(message, message.getAllRecipients());
//            ts.close();
        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 建立郵件:設定發件人、收件人、郵件資訊
     * @param session
     * @return
     * @throws Exception
     */
    @Override
    public Message createEmail(Session session) throws Exception{
        MimeMessage message = new MimeMessage(session);
        // 發件人
        message.setFrom(new InternetAddress(email));
        // 從資料庫中擷取郵箱
        // TODO:擷取訂閱特定主題的網絡威脅資訊的使用者郵箱
        List<String> emails = selectEmail();
        InternetAddress[] sendTo = new InternetAddress[emails.size()];
        for(int i = 0; i < emails.size(); i++){
            log.info("發送到使用者:" + emails.get(i));
            sendTo[i] = new InternetAddress(emails.get(i));
        }
        // 設定收信人
        // TO:收件人、CC:抄送、BCC:密送
        message.setRecipients(Message.RecipientType.TO, sendTo);
        // 設定标題
        message.setSubject("網絡威脅資訊測試标題");
        // 設定郵件内容
        // TODO:從資料庫中擷取要發送的網絡威脅相關資訊
        String info = "網絡威脅相關測試資訊";
        message.setContent(info, "text/html;charset=UTF-8");
        message.saveChanges();
        return message;
    }

    /**
     * 從資料庫中查詢郵箱
     * @return
     */
    @Override
    public List<String> selectEmail(){
        List<Email> emails = emailDOMapper.listEmails();
        List<String> list = emails.stream().map(email -> {
            return email.getEmail();
        }).collect(Collectors.toList());
        return list;
    }
}
           

需要注意的幾點:

1) 類中的一些常量在application.properties中配置

2) QQ郵箱授權碼的擷取方式

QQ郵箱幫助中心之授權碼的擷取方式。隻需要把POP3/SMTP服務開啟即可。