JavaMail小结与注意事项

Wesley13
• 阅读 647

1. 简介

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

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);
    }
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
FD
!(https://oscimg.oschina.net/oscnet/27b94bba9f88488dba7d397aa3cc4f00.gif)
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Java服务总在半夜挂,背后的真相竟然是... | 京东云技术团队
最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这