邮件发送

引入maven dependency

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
	<groupId>javax.mail</groupId>
	<artifactId>mail</artifactId>
	<version>1.4.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
	<version>2.3.28</version>
</dependency>

新建工具类:EmailHelper

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Properties;

/**
 * @author itning
 * @date 2019/6/25 15:58
 */
public class EmailHelper {
    private static final String CHECK_EMAIL_STR = "@";
    private final Configuration configuration;
    private final Builder builder;

    private EmailHelper(Builder builder) throws IOException {
        this.builder = builder;
        this.configuration = new Configuration(Configuration.VERSION_2_3_28);
        this.configuration.setDirectoryForTemplateLoading(new File(builder.templateDir));
        this.configuration.setDefaultEncoding("UTF-8");
    }

    public static class Builder {
        /**
         * 邮件发送者账户(必须设置)
         */
        private String emailSenderUser;
        /**
         * 邮件发送者密码(必须设置)
         */
        private String emailSenderPwd;
        /**
         * HTML模板目录(必须设置)
         */
        private String templateDir;
        /**
         * 抄送者
         */
        private String carbonCopyAddress;
        /**
         * SMTP服务器地址
         */
        private SMTPServer smtpServer;

        /**
         * 设置发送者邮箱(必须设置)
         *
         * @param emailSenderUser 发送者邮箱
         * @return this
         */
        public Builder setEmailSenderUser(String emailSenderUser) {
            this.emailSenderUser = emailSenderUser;
            return this;
        }

        /**
         * 设置发送者邮箱密码(必须设置)
         *
         * @param emailSenderPwd 发送者邮箱密码
         * @return this
         */
        public Builder setEmailSenderPwd(String emailSenderPwd) {
            this.emailSenderPwd = emailSenderPwd;
            return this;
        }

        /**
         * 设置模板目录(必须设置)
         *
         * @param templateDir 模板目录
         * @return this
         */
        public Builder setTemplateDir(String templateDir) {
            this.templateDir = templateDir;
            return this;
        }

        /**
         * 设置抄送者,不设置则没有抄送者
         *
         * @param carbonCopyAddress 抄送者邮箱
         * @return this
         */
        public Builder setCarbonCopy(String carbonCopyAddress) {
            this.carbonCopyAddress = carbonCopyAddress;
            return this;
        }

        /**
         * 设置SMTP服务器地址
         *
         * @param smtpServer SMTP服务器地址
         * @return this
         */
        public Builder setSmtpServer(SMTPServer smtpServer) {
            this.smtpServer = smtpServer;
            return this;
        }

        /**
         * 构建
         *
         * @return EmailHelper
         * @throws IOException IOException
         */
        public EmailHelper build() throws IOException {
            return new EmailHelper(this);
        }
    }

    /**
     * SMTP服务器地址
     */
    public enum SMTPServer {
        /**
         * QQ发送邮件的服务器
         */
        QQ("smtp.qq.com"),
        /**
         * 阿里云邮箱发送邮件的服务器
         */
        ALIYUN("smtp.mxhichina.com"),
        /**
         * 网易邮箱发送邮件的服务器
         */
        NTES("smtp.163.com"),
        /**
         * google邮箱发送邮件的服务器
         */
        GMAIL("smtp.gmail.com"),
        /**
         * 新浪邮箱发送邮件的服务器
         */
        SINA("smtp.sina.com");

        private String server;

        SMTPServer(String server) {
            this.server = server;
        }
    }

    /**
     * 1、创建连接对象
     * 设置邮件发送的协议
     * 设置发送邮件的服务器
     * 填写自己的密钥
     * 2、创建邮件对象
     * 设置发件人
     * 设置收件人
     * 设置抄送者
     * 设置邮件主题
     * 设置邮件内容
     * 3、发送邮件
     *
     * @param to      邮件接收者邮箱
     * @param subject 主题
     * @param content 内容
     */
    public void sendEmail(String to, String subject, String content) throws MessagingException {
        if (!to.contains(CHECK_EMAIL_STR)) {
            throw new IllegalArgumentException("接收者邮箱非法,请检查!");
        }
        Message message = getMessage();
        //2.1设置发件人
        message.setFrom(new InternetAddress(builder.emailSenderUser));
        //2.2设置收件人
        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to));
        //2.3设置抄送者(PS:没有这一条网易会认为这是一条垃圾短信,而发不出去)
        if (builder.carbonCopyAddress != null) {
            message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(builder.carbonCopyAddress));
        }
        //2.4设置邮件的主题
        message.setSubject(subject);
        //2.5设置邮件的内容
        message.setContent("" + content + "", "text/html;charset=utf-8");
        // 3、发送邮件
        Transport.send(message);
    }

    /**
     * 发送邮件带附件
     *
     * @param to      邮件接收者邮箱
     * @param subject 主题
     * @param content 内容
     */
    public void sendEmail(String to, String subject, String content, File annexFile) throws MessagingException, UnsupportedEncodingException {
        if (!to.contains(CHECK_EMAIL_STR)) {
            throw new IllegalArgumentException("接收者邮箱非法,请检查!");
        }
        Message message = getMessage();
        // 发件人
        InternetAddress from = new InternetAddress(builder.emailSenderUser);
        message.setFrom(from);
        // 收件人
        InternetAddress re = new InternetAddress(to);
        message.setRecipient(Message.RecipientType.TO, re);
        if (builder.carbonCopyAddress != null) {
            message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(builder.carbonCopyAddress));
        }
        // 邮件主题
        message.setSubject(subject);
        Multipart multipart = new MimeMultipart();
        //添加邮件正文
        BodyPart contentPart = new MimeBodyPart();
        contentPart.setContent(content, "text/html;charset=UTF-8");
        multipart.addBodyPart(contentPart);
        //添加邮件附件
        BodyPart attachmentBodyPart = new MimeBodyPart();
        DataSource source = new FileDataSource(annexFile);
        attachmentBodyPart.setDataHandler(new DataHandler(source));
        //MimeUtility.encodeWord可以避免文件名乱码
        attachmentBodyPart.setFileName(MimeUtility.encodeWord(annexFile.getName()));
        multipart.addBodyPart(attachmentBodyPart);
        message.setContent(multipart);
        Transport.send(message);
    }

    /**
     * 发送HTML模板邮件
     *
     * @param templateName 模板名
     * @param dataMap      数据
     * @param to           邮件接收者邮箱
     * @param subject      主题
     * @throws TemplateException  if an exception occurs during template processing
     * @throws IOException        if an I/O exception occurs during writing to the writer.
     * @throws MessagingException 邮件发送异常
     */
    public void sendHtmlEmail(String to, String subject, String templateName, Map<String, Object> dataMap) throws IOException, TemplateException, MessagingException {
        //获取模板
        Template template = configuration.getTemplate(templateName);
        StringWriter stringWriter = new StringWriter();
        //生成HTML
        template.process(dataMap, stringWriter);
        stringWriter.flush();
        sendEmail(to, subject, stringWriter.toString());
    }

    /**
     * 发送HTML模板邮件带附件
     *
     * @param templateName 模板名
     * @param dataMap      数据
     * @param to           邮件接收者邮箱
     * @param subject      主题
     * @throws TemplateException  if an exception occurs during template processing
     * @throws IOException        if an I/O exception occurs during writing to the writer.
     * @throws MessagingException 邮件发送异常
     */
    public void sendHtmlEmail(String to, String subject, String templateName, Map<String, Object> dataMap, File annexFile) throws IOException, TemplateException, MessagingException {
        //获取模板
        Template template = configuration.getTemplate(templateName);
        StringWriter stringWriter = new StringWriter();
        //生成HTML
        template.process(dataMap, stringWriter);
        stringWriter.flush();
        sendEmail(to, subject, stringWriter.toString(), annexFile);
    }

    private Message getMessage() {
        //1、创建连接对象
        Properties props = new Properties();
        //1.1设置邮件发送的协议
        props.put("mail.transport.protocol", "smtp");
        //1.2设置发送邮件的服务器
        props.put("mail.smtp.host", builder.smtpServer.server);
        //1.3需要经过授权,也就是有户名和密码的校验,这样才能通过验证(一定要有这一条)
        props.put("mail.smtp.auth", "true");
        //1.4下面一串是发送邮件用465端口,如果不写就是以25端口发送,阿里云已经关闭了25端口
        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        //1.5认证信息
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(builder.emailSenderUser, builder.emailSenderPwd);
            }
        });
        //2、创建邮件对象
        return new MimeMessage(session);
    }
}

发送邮件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * @author itning
 * @date 2019/6/25 14:53
 */
public class Test {
    public static void main(String[] args) throws IOException, TemplateException, MessagingException {
        EmailHelper emailHelper = new EmailHelper.Builder()
                //发送者邮箱
                .setEmailSenderUser("xxx@qq.com")
                //密码
                .setEmailSenderPwd("")
                //HTML模板目录
                .setTemplateDir("G:\\ProjectData\\IdeaProjects\\Test\\src\\main\\resources")
                //抄送邮箱
                .setCarbonCopy(null)
                //发信邮箱服务器
                .setSmtpServer(EmailHelper.SMTPServer.QQ)
                .build();

        Map<String, Object> dataMap = Collections.singletonMap("name", "模板生成的字符串");
        emailHelper.sendHtmlEmail("itning@itning.top", "这是主题", "temp.ftl", dataMap);
    }
}
  • 发送普通邮件:sendEmail(String to, String subject, String content)

  • 发送普通带附件邮件:sendEmail(String to, String subject, String content, File annexFile)

  • 发送HTML邮件:sendHtmlEmail(String to, String subject, String templateName, Map<String, Object> dataMap)

  • 发送HTML带附件邮件:sendHtmlEmail(String to, String subject, String templateName, Map<String, Object> dataMap, File annexFile)

模板内容:temp.ftl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>模板</title>
</head>
<body>
展示HTML邮件能力
<a href="https://blog.itning.top">超链接</a>
<img src="https://avatars1.githubusercontent.com/u/19759891?s=460&v=4" alt="图片">
<br>
以下文字模板生成:
<h1>${name}</h1>
</body>
</html>

FreeMarker 模板中文官方参考手册

已接收:

email