锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

使用Java Email发送邮件

时间:2023-11-04 23:37:01 uxr抗硫化厚膜芯片电阻

前言Email是电子邮件。电子邮件的应用已经有几十年的历史了。我们熟悉的邮箱地址,如电子邮件abc@example.com,比如邮件软件Outlook、网易闪电邮,Foxmail都是用来收发邮件的。当然,使用Java也可以收发电子邮件

让我们来看看传统邮件是如何发送的:传统邮件是通过邮局发送的,然后从一个邮局到另一个邮局,最后到达用户的邮箱。

电子邮件的发送过程也类似,但电子邮件来自用户电脑的电子邮件软件,如Outlook,将其发送到邮件服务器,可通过多个邮件服务器中转,最终到达对方的邮件服务器,收件人可通过软件接收邮件:

             ┌─────────┐    ┌─────────┐    ┌─────────┐              │?????????│    │?????????│    │?????????│ ┌───────┐    ├─────────┤    ├─────────┤    ├─────────┤    ┌───────┐ │???????│    │?????????│    │?????????│    │?????????│    │???????│ ├───────┤    ├─────────┤    ├─────────┤    ├─────────┤    ├───────┤ │       │───>│O ???????│───>│O ???????│───>│O ???????│<───│       │ └───────┘    └─────────┘    └─────────┘    └─────────┘    └───────┘    MUA           MTA            MTA            MDA           MUA

我们把类似Outlook这种邮件软件叫MUA:Mail User Agent,意思是为用户服务的邮件代理;邮件服务器称为MTA:Mail Transfer Agent,意思是邮件中转代理;最终到达的邮件服务器称为MDA:Mail Delivery Agent,意思是邮件到达的代理。一旦电子邮件到达MDA,不再动了。事实上,电子邮件通常存储在MDA在服务器硬盘上,等待收件人通过软件或登录浏览器查看电子邮件。

SMTP 的全称是“Simple Mail Transfer Protocol即简单的邮件传输协议。它是一组从源地址到目的地址传输邮件的规范,通过它来控制邮件的传输。SMTP 协议属于 TCP/IP 协议簇帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器遵循 SMTP 发送协议邮件服务器。 SMTP 简单地说,认证需要在提供账户名和密码后才能登录 SMTP 服务器,这使得垃圾邮件的传播者没有机会。

邮件协议

MTA和MDA这种服务器软件通常是现成的,我们通常不关心这些邮件服务器是如何运行的。更多的需求场景需要发送电子邮件。例如:促销商品邮件、验证码邮件、消息通知邮件等。常见的电子邮件协议包括:POP3、SMTP、IMAP。
POP3
POP3是Post Office Protocol 简称3,即邮局协议的第三个版本,规定如何连接个人电脑Internet下载电子邮件的邮件服务器和电子协议。这是因特网电子邮件的第一个离线协议标准,POP3允许用户将电子邮件从服务器存储到本地主机(即自己的计算机),并删除电子邮件服务器上的电子邮件POP3服务器遵循POP接收电子邮件邮件的协议接收邮件服务器。(与IMAP有什么区别?)
SMTP
SMTP 的全称是“Simple Mail Transfer Protocol即简单的邮件传输协议。它是一组从源地址到目的地址传输邮件的规范,通过它来控制邮件的传输。SMTP 协议属于 TCP/IP 协议簇帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器遵循 SMTP 发送协议邮件服务器。 SMTP 简单地说,认证需要在提供账户名和密码后才能登录 SMTP 服务器,这使得垃圾邮件的传播者没有机会。 增加 SMTP 认证的目的是防止用户被垃圾邮件入侵。
IMAP
IMAP全称是Internet Mail Access Protocol,即交互式电子邮件访问协议,它与POP类似邮件访问标准协议之一。不同的是,它打开了IMAP之后,您在电子邮件客户端收到的电子邮件仍然保留 在服务器上,客户端上的操作会反馈给服务器,比如删除邮件、标记已读等。,服务器上的邮件也会做相应的动作。因此,无论是从浏览器还是客户端登录邮箱 软件登录邮箱,看到的邮件以及状态都是一致的。
IMAP和POP3有什么区别?
POP3协议允许电子邮件客户下载服务器上的电子邮件,但客户操作(如移动电子邮件、标记已读等)不会反馈给服务器,如通过客户收集电子邮件中的三封电子邮件并移动到其他文件夹,电子邮件服务器上的电子邮件不同时移动 。
IMAP提供webmail 对于与电子邮件客户端的双向通信,客户端的操作将反馈给服务器。对于电子邮件的操作,服务器上的电子邮件也会做出相应的动作。

因此,当我们关心如何实现邮件发送时,我们实际上是在编写一个MUA发送邮件的软件MTA上。MUA到MTA发邮件的协议是SMTP协议,它是Simple Mail Transport Protocol缩写,标准端口25,加密端口465或587。SMTP协议是基于的TCP任何程序发送电子邮件都必须遵守上述协议SMTP协议。使用Java当程序发送电子邮件时,我们不需要关心SMTP只需使用协议的底层原理JavaMail这个标准API邮件可以直接发送。

准备SMTP登录信息

常用的邮件服务提供商SMTP信息:
●QQ邮箱:SMTP服务器是smtp.qq.com,端口是465/587
●163邮箱:SMTP服务器是smtp.163.com,端口是465
●126邮箱:SMTP服务器是smtp.126.com,端口是25
●Gmail邮箱:SMTP服务器是smtp.gmail.com,端口是465/587

准备好SMTP登录信息后,我们必须首先检查JavaMail相关的依赖Jar包javax.mail-1.6.2.jar加入当前项目。(相关。jar包在我上传的资源中)

然后,我们通过JavaMail API连接到SMTP以25端口为例,连接服务器SMTP服务器需要准备一个Properties对象,填写相关信息。最后获取Session例如,如果服务器需要认证,则需要输入Authenticator返回指定的用户名和密码。当我们得到它时Session例子打开后,可以看到调试模式SMTP通信的详细内容便于调试。

这个代码相当于登录你的电子邮件。如果您需要发送电子邮件,您必须首先登录并存储您的用户名和密码Session对象中

  // SMTP服务器地址   String smtp = "smtp.163.com";      ///邮箱账号和密码(授权密码)   String userName = "zf5209926@163.com";   String password = "***FLMDZTIROSCL";      Properties props = new Properties();   props.put("mail.smtp.host", smtp); // SMTP主机名   props.put("mail.smtp.port", "25"); // 主机端口号   props.put("mail.smtp.auth", "true"); // 是否需要用户认证   props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密         // 创建Session   // 参数1:SMTP连接服务器的信息   // 参数2: 用户认证对象(Authenticator匿名实现类接口)   Session session = Session.getInstance(props, new Authenticator() {    @Override    protected PasswordAuthentication getPasswordAuthentication() {          return new PasswordAuthentication(userName,password);    }   });      // 打开调试模式   session.setDebug(true);

发送HTML邮件

发送邮件时,我们需要构造一个Message对象,然后调用Transport.send(Message)可完成发送:绝大多数邮件服务器要求发送方地址与登录用户名一致,否则发送将失败。

try {    Session session = JavaMailUtils.createSession();    String text = "我来自于蛮荒,直至存活至公元2111年,这是给过去的我的";        // 2.创建邮件对象(Message抽象子类对象)    MimeMessage msg = new MimeMessage(session); // 传入session对象    msg.setFrom(new InternetAddress("zf5209926@163.com")); // 发件人    msg.setRecipient(RecipientType.TO, new InternetAddress("***4318***@qq.com")); // 收件人    msg.setSubject("你来自未来", "utf-8"); // 标题    msg.setText(text, "utf-8", "html"); // 正文     // 3.发送邮件    Transport.send(msg);		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
msg.setText(text, "utf-8", "html"); // 设置以html格式发送

然后运行上述代码块,我们可以在控制台看到JavaMail打印的调试信息:

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=王智博, password=
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 DESKTOP-LP308OO
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFz4Li7UCa0xDrUUUUj
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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFz4Li7UCa0xDrUUUUj"
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 DESKTOP-LP308OO
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrxLpU0UCa0xDrUUUUj
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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrxLpU0UCa0xDrUUUUj"
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=zf5209926@163.com, password=
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:
250 Mail OK
RCPT TO:<*******@qq.com>
250 Mail OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   *******@qq.com
DATA
354 End data with .
Date: Sun, 17 Jul 2022 18:11:08 +0800 (CST)
From: zf5209926@163.com
To: *******@qq.com
Message-ID: <1585787493.0.1658052668941@DESKTOP-LP308OO>
Subject: =?utf-8?B?5p2l6Ieq5pyq5p2l55qE5L2g?=
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

5oiR5p2l6Ieq5LqO6Juu6I2S77yM55u06Iez5a2Y5rS76Iez5YWs5YWDPGI+MjExMTwvYj7lubTv
vIzov5nmmK/lj5Hnu5nov4fljrvnmoTmiJE=
.
250 Mail OK queued as smtp9,DcCowACHWy094NNid5E6QA--.58681S3 1658052672
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 Bye

当出现221 Bye则代表发送成功

发送附件

要在电子邮件中携带附件,我们就不能直接调用message.setText()方法,而是要构造一个Multipart对象:

try {
			Session session = JavaMailUtils.createSession();
			String text = "我来自于蛮荒,直至存活至公元2111年,这是发给过去的我";
			
			// 2.创建邮件对象(Message抽象类的子类对象)
			MimeMessage msg = new MimeMessage(session); // 传入session对象
			msg.setFrom(new InternetAddress("zf5209926@163.com")); // 发件人
			msg.setRecipient(RecipientType.TO, new InternetAddress("********@qq.com")); // 收件人
			msg.setSubject("来自未来的你", "utf-8"); // 标题

			// 邮件内容"复合"对象
			Multipart multipart = new MimeMultipart();

			// 正文
			BodyPart textPart = new MimeBodyPart();
			// 参数1:正文内容
			// 参数2: 内容类型 ; 字符编码集
			textPart.setContent(text, "text/html;charset=utf-8");

			// 附件
			BodyPart imagePart = new MimeBodyPart();
			imagePart.setFileName("WSY.jpg");
			// 数据处理对象()
			imagePart.setDataHandler(new DataHandler(
					new ByteArrayDataSource(Files.readAllBytes(Paths.get("C:\\Users\\王智博\\Pictures\\Saved Pictures\\ya.jpg")),
							"application/octet-stream")));

			// 添加至邮件内容
			multipart.addBodyPart(textPart); // 添加正文
			multipart.addBodyPart(imagePart); // 添加附件

			// 设置邮件内容
			msg.setContent(multipart);

			Transport.send(msg);

		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

可以理解为将正文和附件分别先存入BodyPart对象中,然后在使用Multipart对象将其合并打包给MimeMessage,然后发送即可。

一个Multipart对象可以添加若干个BodyPart,其中第一个BodyPart是文本,即邮件正文,后面的BodyPart是附件。BodyPart依靠setContent()决定添加的内容,如果添加文本,用setContent("...", "text/plain;charset=utf-8")添加纯文本,或者用setContent("...", "text/html;charset=utf-8")添加HTML文本。如果添加附件,需要设置文件名(不一定和真实文件名一致),并且添加一个DataHandler(),传入文件的MIME类型。二进制文件可以用application/octet-stream,Word文档则是application/msword。
最后,通过setContent()把Multipart添加到Message中,即可发送。

发送内嵌图片的HTML邮件

如果需要在HTML邮件中内嵌图片,可以选择在邮件中加入,这样的外部图片链接通常会被邮件客户端过滤,并提示用户显示图片并不安全。只有内嵌的图片才能正常在邮件中显示。所以,这种方式并不推荐。
推荐将内嵌图片作为一个附件嵌入邮件,即邮件本身也是Multipart,但需要做一点额外的处理

// 创建MimeMessage邮件信息对象
// ...略

// 创建Multipart复合对象
Multipart multipart = new MimeMultipart();
					
// 添加text:
BodyPart textpart = new MimeBodyPart();
textpart.setContent("

Hello

", "text/html;charset=utf-8"); multipart.addBodyPart(textpart); // 添加image: BodyPart imagepart = new MimeBodyPart(); imagepart.setFileName("lvjuren.jpg"); imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(文件流字节数组, "application/octet-stream"))); // 设置当前image为内嵌图片 // 这个ID和HTML中引用的ID对应起来,邮件客户端就可以正常显示内嵌图片 imagepart.setHeader("Content-ID", ""); multipart.addBodyPart(imagepart);

这样就可以实现内嵌图片的发送

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章