JavaMail小结与注意事项

1. 简介

Java的发送邮件的组合一直让人比较困惑,这里做一个简单的小结和说明一些注意事项。

在这里插入图片描述
MimeBodyPart可以是文本、HTML、图片附件,也可以是MimeMultiPart。

MimeMultiPart是多个MimeBodyPart的组合,这样就可以通过嵌套的方式完成复杂邮件的组合。

2. sender与from

mimeMessage.setFrom(fromAddress);
mimeMessage.setSender(senderAddress);

from:表示邮件是谁发的,必须和下面的transport连接的时候使用的user一致:

transport.connect(host, user, pass);

sender:sender表示发件人,邮件中可以看到发件人可以看到sender代表from发送,使用的用户名和密码还是from的。

如果想要让邮件显眼,一看就知道是谁发的,可以使用:

title<邮箱地址>

例如:

InternetAddress fromAddress = new InternetAddress(String.format("%s<%s>",MimeUtility.encodeText("技术部"),from));

MimeUtility.encodeText可以处理中文问题。

3. RecipientType

  1. Message.RecipientType.TO :接收
  2. Message.RecipientType.CC :抄送
  3. Message.RecipientType.BCC:密送

4. Multipart subtype

mimeMultipart.setSubType("related");
  1. mixed:混合关系,一般正文和附件组合使用mixed,如果不设置,javamail默认会使用mixed
  2. related:关联关系,一般html引用了图片这类内嵌资源,正文和图片组合使用related
  3. alternative:同时存在纯文本与超文本,使用boundary分割

邮件可能会分段,使用的是boundary中定义的字符串作为标识。

  1. 段体内的每个子段以:【–加boundary】行开始
  2. 父段则以:【–加boundary加–】行结束
  3. 不同段之间用空行分隔

大概像下面这样的:

Content-Type: multipart/mixed; 
	boundary="----=_Part_1_293907205.1610941392421"

------=_Part_1_293907205.1610941392421
Content-Type: multipart/related; 
	boundary="----=_Part_0_1259652483.1610941392409"

------=_Part_0_1259652483.1610941392409
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-ID: haha

可以使用:

mimeMessage.writeTo(new FileOutputStream("G:\\picture\\tmp.eml"));

将邮件保存到本地,然后使用文本编辑器打开查看。

5. Store与Folder

5.1 Store

Store表示存储邮件的服务器,接收邮件

// 存储邮件的服务器,采用pop3协议
Store store = session.getStore("pop3");
    
// 连接邮件服务器
store.connect(host,username,passworsd)

5.2 Folder

Folder表示收件箱目录对象

Folder folder = store.getFolder("tmp");

// 以只读的方式打开目录
folder.open(Folder.READ_ONLY);
 
// 获取目录下的邮件信息
Message message[ ] = folder.getMessages();

6. 示例

public enum MailConfig {
M163("mail.163.com","xxx@163.com","xxx");
    private String server;
    private String user;
    private String pass;

    MailConfig(String server, String user, String pass) {
        this.server = server;
        this.user = user;
        this.pass = pass;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    public String getServer() {
        return server;
    }

    public void setServer(String server) {
        this.server = server;
    }
}

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class MailSenderHelper {

    public static Session getSession(MailConfig config){
        Properties properties = new Properties();
        properties.setProperty("mail.host", config.getServer());
        properties.setProperty("mail.transport.protocol", "smtp");
        properties.setProperty("mail.smtp.auth", "true");
        Session session = Session.getInstance(properties);
        session.setDebug(false);
        return session;
    }

    public static Transport getTransport(MailConfig config) throws MessagingException {
        Session session = getSession(config);
        Transport transport = session.getTransport();
        transport.connect(config.getServer(), config.getUser(), config.getPass());
        return transport;
    }

    public static void send(MailConfig config, MimeMessage mimeMessage) throws MessagingException {
        Transport transport = getTransport(config);
        transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
        transport.close();
    }
}
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import java.util.Date;
import java.util.List;


public class HtmlEmailHelper {

    private static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=UTF-8";

    private static final String UTF8 = "UTF-8";

    public static void sendHtmlEmail(
            MailConfig config,
            String from,
            String nickname,
            List<String> tos,
            String subject,
            String html,
            List<String> imgs,
            List<String> attachs
    ) throws Exception{
        Session session = MailSenderHelper.getSession(config);
        MimeMessage mimeMessage = new MimeMessage(session);
//        InternetAddress senderAddress = new InternetAddress(config.getUser());
//        InternetAddress fromAddress = new InternetAddress(from);

        InternetAddress fromAddress = new InternetAddress(String.format("%s<%s>",MimeUtility.encodeText("技术部"),config.getUser()));
        InternetAddress senderAddress = new InternetAddress(String.format("%s<%s>",MimeUtility.encodeText(nickname),from));
//        if(StringUtils.isNotBlank(nickname)){
//            mimeMessage.setFrom(new InternetAddress(String.format("%s<%s>",nickname,from)));
//        }else {
//            mimeMessage.setFrom(fromAddress);
//        }
        mimeMessage.setFrom(fromAddress);
        mimeMessage.setSender(senderAddress);
        for (String to : tos) {
            mimeMessage.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to));
        }
        mimeMessage.setSubject(subject,UTF8);
        DataHandler dh;
        FileDataSource fileDataSource;

        MimeMultipart mimeMultipart = new MimeMultipart();//html 与 图片
        // 添加图片部分
        if(imgs != null && imgs.size() > 0) {
            for (String img : imgs) {
                MimeBodyPart image = new MimeBodyPart();
                fileDataSource = new FileDataSource(img);
                dh = new DataHandler(fileDataSource);
                image.setDataHandler(dh);
                String name = dh.getName();
                int dotIndex = name.lastIndexOf(".");
                if(dotIndex != -1){
                    name = name.substring(0,dotIndex);
                }
                String contentID = MimeUtility.encodeText(name);
                image.setContentID(contentID);//<img src='cid:contentID'/>
                mimeMultipart.addBodyPart(image);
            }
        }

        // 添加HTML节点
        MimeBodyPart text = new MimeBodyPart();
        text.setContent(html, TEXT_HTML_CHARSET_UTF_8);

        // 将HTML和图片合成一个MimeMultiPart
        mimeMultipart.addBodyPart(text);
        // 因为html可能引用图片,所以关系设置为related,这样图片就不会显示在附件中
        mimeMultipart.setSubType("related");


        // 新建一个MimeMultipart存放最终内容:HTML图片部分 + 附件
        MimeMultipart mailMimeMultipart = new MimeMultipart();
        // 将HTML与图片的MimeMultiPart混合部分封装成一个MimeBodyPart
        MimeBodyPart txtImgMimeBodyPart = new MimeBodyPart();
        txtImgMimeBodyPart.setContent(mimeMultipart);

        // 添加HTML图片部分
        mailMimeMultipart.addBodyPart(txtImgMimeBodyPart);

        // 添加附件部分
        MimeBodyPart attachment;
        if(attachs != null && attachs.size() > 0) {
            for (String attach : attachs) {
                attachment = new MimeBodyPart();
                fileDataSource = new FileDataSource(attach);
                dh = new DataHandler(fileDataSource);
                attachment.setDataHandler(dh);
                attachment.setFileName(MimeUtility.encodeText(dh.getName()));
                mailMimeMultipart.addBodyPart(attachment);
            }
        }

        // HTML图片部分一般和附件没啥直接关系,所以关联关系设置为mixed
//        mailMimeMultipart.setSubType("mixed");
        mailMimeMultipart.setSubType("alternative");

        // 将MimeMessage的内容设置为组合好的最后的MimeMultipart部分
        mimeMessage.setContent(mailMimeMultipart);
        //设置邮件的发送时间,默认立即发送
        mimeMessage.setSentDate(new Date());

//        mimeMessage.saveChanges();
        //将邮件写入指定的路径
//        mimeMessage.writeTo(new FileOutputStream("G:\\picture\\tmp.eml"));
        MailSenderHelper.send(config,mimeMessage);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值