赞
踩
本篇技术博客整理和总结了JavaMail发送各种不同类型的邮件的案例,以及其中的实现步骤和细节。
目录
使用JAVA程序进行发送邮件,使用的是SMTP协议,它是 Simple Mail Transport Protocol 的缩写,使用标准端口 25 ,也可以使用加密端口 465 或 587 。 SMTP 协议是一个建立在 TCP 之上的协议,任何程序发送邮件都必须遵守 SMTP 协议。使用 Java 程序发送邮件时,我们无需关心 SMTP 协议的底层原理,只需要使用 JavaMail这个标准 API 就可以直接发送邮件。
首先我们要准备SMTP的登录信息,本人使用的是163邮箱,下面是不同常用邮件服务商的SMTP信息:
准备好登录信息后,需要将相关jar包javax.mail-1.6.2.jar导入到项目中。
然后,我们通过 JavaMail API 连接到 SMTP 服务器上:连接 SMTP 服务器时, 需要准备一个 Properties 对象,填入相关信息。最后创建Session实例时,调用Session.getInstance()方法,第一个参数传入服务器的连接信息properties对象,第二个参数传入Authenticator对象返回用户名和密码用于服务器的认证。当我们获取到 Session 实例后,调用session实例的setDebug()方法打开调试模式可以看到 SMTP 通信的详细内容,便于调试。
这里将session实例的创建过程封装成了一个类中的静态方法,以便于后面session实例的创建。
- import java.util.Properties;
-
- import javax.mail.Authenticator;
- import javax.mail.PasswordAuthentication;
- import javax.mail.Session;
-
- public final class JavaMailUtils {
- private JavaMailUtils() {
-
- }
-
- public static Session createSession() {
- //邮箱账号信息
- String userName = "m18391125066@163.com";// 邮箱发送账号
- String password = "SDBHWNAOUZZAXRLH";// 账号授权密码
-
- //SMTP服务器连接信息
- Properties props = new Properties();
- props.put("mail.smtp.host", "smtp.163.com"); // STMP主机名
- props.put("mail.smtp.port", "25"); // 主机端口号
- props.put("mail.smtp.auth", "true"); // 是否需要用户认证
- props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密
-
- //创建session对话
- // 参数1: smtp服务器连接参数
- // 参数2: 账号和密码的授权认证对象
- Session session = Session.getInstance(props, new Authenticator() {
-
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- // TODO Auto-generated method stub
- return new PasswordAuthentication(userName, password);
- }
-
- });
- session.setDebug(true);
- return session;
- }
- }
第一步,创建session会话。
使用之前封装好的方法创建session对象。
- // 1.创建session对话
- Session session = JavaMailUtils.createSession();
第二步,创建邮件对象并设置相关信息。
- // 2.创建邮件对象
- MimeMessage message = new MimeMessage(session);
- message.setSubject("这是来自Gypppppppppppppp的邮件"); // 设置邮件标题
- message.setText("hahhhhhhhhhh","utf-8"); // 设置邮件正文
- message.setFrom(new InternetAddress("此处为发件人的邮箱")); //设置发件人
- message.setRecipient(RecipientType.TO,newInternetAddress("此处为收件人的邮箱")); //设置收件人
第三步,发送邮件。
- // 3.发送邮件
- Transport.send(message);
发送至qq邮箱:
将调试信息打印到控制台上,我们可以看出: SMTP协议是一个请求-响应协议,客户端总是发送命令,然后等待服务器响应。服务器响应总是以数字开头,后面的信息才是用于调试的文本。 这些响应码已经被定义在SMTP协议中了,查看具体的响应码就可以知道出错原因。
- DEBUG: setDebug: JavaMail version 1.6.2
- DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
- DEBUG SMTP: need username and password for authentication
- DEBUG SMTP: protocolConnect returning false, host=smtp.163.com, user=18018, password=<null>
- DEBUG SMTP: useEhlo true, useAuth true
- DEBUG SMTP: trying to connect to host "smtp.163.com", port 25, isSSL false
- 220 163.com Anti-spam GT for Coremail System (163com[20141201])
- DEBUG SMTP: connected to host "smtp.163.com", port: 25
- EHLO LAPTOP-6GE885FP
- 250-mail
- 250-PIPELINING
- 250-AUTH LOGIN PLAIN XOAUTH2
- 250-AUTH=LOGIN PLAIN XOAUTH2
- 250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFw9LV7UCa0xDrUUUUj
- 250-STARTTLS
- 250-ID
- 250 8BITMIME
- DEBUG SMTP: Found extension "PIPELINING", arg ""
- DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2"
- DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN XOAUTH2"
- DEBUG SMTP: Found extension "coremail", arg "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFw9LV7UCa0xDrUUUUj"
- DEBUG SMTP: Found extension "STARTTLS", arg ""
- DEBUG SMTP: Found extension "ID", arg ""
- DEBUG SMTP: Found extension "8BITMIME", arg ""
- STARTTLS
- 220 Ready to start TLS
- EHLO LAPTOP-6GE885FP
- 250-mail
- 250-PIPELINING
- 250-AUTH LOGIN PLAIN XOAUTH2
- 250-AUTH=LOGIN PLAIN XOAUTH2
- 250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UryxxwZUCa0xDrUUUUj
- 250-STARTTLS
- 250-ID
- 250 8BITMIME
- DEBUG SMTP: Found extension "PIPELINING", arg ""
- DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2"
- DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN XOAUTH2"
- DEBUG SMTP: Found extension "coremail", arg "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UryxxwZUCa0xDrUUUUj"
- DEBUG SMTP: Found extension "STARTTLS", arg ""
- DEBUG SMTP: Found extension "ID", arg ""
- DEBUG SMTP: Found extension "8BITMIME", arg ""
- DEBUG SMTP: protocolConnect login, host=smtp.163.com, user=m18391125066@163.com, password=<non-null>
- DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
- DEBUG SMTP: Using mechanism LOGIN
- DEBUG SMTP: AUTH LOGIN command trace suppressed
- DEBUG SMTP: AUTH LOGIN succeeded
- DEBUG SMTP: use8bit false
- MAIL FROM:<m18391125066@163.com>
- 250 Mail OK
- RCPT TO:<1801875581@qq.com>
- 250 Mail OK
- DEBUG SMTP: Verified Addresses
- DEBUG SMTP: 1801875581@qq.com
- DATA
- 354 End data with <CR><LF>.<CR><LF>
- Date: Sat, 8 Jul 2023 19:58:44 +0800 (CST)
- From: m18391125066@163.com
- To: 1801875581@qq.com
- Message-ID: <1028214719.0.1688817524899@LAPTOP-6GE885FP>
- Subject: =?GBK?Q?=D5=E2=CA=C7=C0=B4=D7=D4Gyppppppppppppppppppppppp?=
- =?GBK?Q?ppppppppppppppppppppppppppp=B5=C4=D3=CA=BC=FE?=
- MIME-Version: 1.0
- Content-Type: text/plain; charset=utf-8
- Content-Transfer-Encoding: 7bit
-
- hahhhhhhhhhhhhhh
- .
- 250 Mail OK queued as zwqz-smtp-mta-g1-3,_____wA3hi51T6lkpTUyCA--.50930S3 1688817527
- DEBUG SMTP: message successfully delivered to mail server
- QUIT
- 221 Bye
和发送文本邮件类似,只需要在message.setText(body,"utf-8")的基础上传入第三个参数"html",即message.setText(body,"utf-8","html"),这样正文中就可以识别html标签并展示相应的效果。
message.setText("<b>hahhhhh</b>hhhhhhhhh","utf-8","html"); // 设置邮件正文
要想携带附件,setText()方法就不再适用,而是要构造一个Multipart对象:
- //邮件中既包含正文,又包含附件正文
- //正文
- BodyPart textPart = new MimeBodyPart();
- StringBuilder contentText = new StringBuilder();
- contentText.append("<h3>海边的曼彻斯特</h3>");
- contentText.append("<p>I cant beat it</p>");
- textPart.setContent(contentText.toString(),"text/html;charset=utf-8");
-
- //附件
- BodyPart imagePart = new MimeBodyPart();
- imagePart.setFileName("附件名称");
- imagePart.setDataHandler(new DataHandler(
- new ByteArrayDataSource(Files.readAllBytes(Paths.get("d:\\file\\Manchester.webp")), "application/octet-stream")));
-
- //将正文和附件部分组装成Multipart对象
- Multipart multipart = new MimeMultipart();
- multipart.addBodyPart(textPart);
- multipart.addBodyPart(imagePart);
-
- //将multipart对象放入邮件
- message.setContent(multipart);
运行结果: 带有附件
如果需要在HTML邮件中内嵌图片,可以选择在html邮件中加入<img src=""> 的标签,这样的外部图片链接通常会被邮件客户端过滤,并提示用户显示图片并不安全。只有内嵌的图片才能正常在邮件中显示。所以,这种方式并不推荐。
推荐将内嵌图片作为一个附件嵌入邮件,即邮件本身也是 Multipart ,但需要在带有附件的邮件发送程序上做一点额外的处理:
- contentText.append("<img scr=\"cid:Manchester\">"); // 在正文部分中加入html标签
- imagePart.setHeader("Content-ID","Manchester");// 在附件部分设置图片内容的id
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。