资讯详情

Java Email——使用Java程序收发电子邮件

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在服务器硬盘上,等待收件人通过软件或登录浏览器查看电子邮件。

MTA和MDA这种服务器软件通常是现成的,我们通常不关心这些邮件服务器是如何运行的。更多的需求场景需要发送电子邮件。例如:促销商品邮件、验证码邮件、消息通知邮件等。常见的电子邮件协议包括:POP3、SMTP、IMAP。

POP3是Post Office Protocol 简称3,即邮局协议的第三个版本,规定如何连接个人电脑Internet下载电子邮件的邮件服务器和电子协议。这是因特网电子邮件的第一个离线协议标准,POP3允许用户将电子邮件从服务器存储到本地主机(即自己的计算机),并删除电子邮件服务器上的电子邮件POP3服务器则是遵循POP接收电子邮件邮件的协议接收邮件服务器。

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

IMAP全称是Internet Mail Access Protocol,即交互式电子邮件访问协议,它与POP类似邮件访问标准协议之一。不同的是,它打开了IMAP之后,您在电子邮件客户端收到的电子邮件仍然保留 在服务器上,客户端上的操作会反馈给服务器,比如删除邮件、标记已读等。,服务器上的邮件也会做相应的动作。因此,无论是从浏览器还是客户端登录邮箱 软件登录邮箱,看到的邮件和状态一致。

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

假设我们要用自己的邮件地址me@example.com给令狐冲发邮件,已知令狐冲的邮件地址是xiaoming@somewhere.com,在发送邮件之前,我们必须首先确定它MTA邮件服务器地址及端口号。邮件服务器地址通常是smtp.example.com,邮件服务提供商确定端口号是25、465还是587。

常用的邮件服务提供商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加入当前项目。

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

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

发送纯文本邮件代码如下:

package com.hpc.wyj01;  import javax.mail.Message; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage;  /**  * 发送纯文本邮件  * @author 我  *  */ public class Demo02 {  public static void main(String[] args) {   try {    //创建Session会话    Session session=Javacreatsession.creatSession();        //2.创建邮件对象(Message抽象子类对象)    MimeMessage msg=new MimeMessage(session);    msg.setFrom(new InternetAddress("wyj000716@126.com"));    msg.setRecipient(RecipientType.TO, new InternetAddress("464822504@qq.com"));    msg.setSubject("魏雨娇发来的邮件","utf-8");    msg.setText("他说他是个人<b>美女</b>","utf-8","html");    //3.发邮件    Transport.send(msg);       } catch (AddressException e) {    e.printStackTrace();   } catch (MessagingException e) {    e.printStackTrace();   }  }  }

我们可以在控制台上看到上述代码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.126.com, user=我, password=<null> DEBUG SMTP: useEhlo true, useAuth true DEBUG SMTP: trying to connect to host "smtp.126.com", port 25, isSSL false 220 126.com Anti-spam GT for Coremail System (126com[20140526]) DEBUG SMTP: connected to host "smtp.126.com", port: 25 EHLO baby 250-mail 250-PIPELINING 250-AUTH LOGIN PLAIN XOAUTH2 250-AUTH=LOGIN PLAIN XOAUTH2 250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UruSlYDUCa0xDrUUUUj 250-STARTTLS 250-ID 250 8BITMIME DEBUG MTP: 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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UruSlYDUCa0xDrUUUUj"
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 baby
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrvvEerUCa0xDrUUUUj
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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrvvEerUCa0xDrUUUUj"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ID", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.126.com, user=wyj000716@126.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:<wyj000716@126.com>
250 Mail OK
RCPT TO:<464822504@qq.com>
250 Mail OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   464822504@qq.com
DATA
354 End data with <CR><LF>.<CR><LF>
Date: Sun, 17 Jul 2022 18:50:06 +0800 (CST)
From: wyj000716@126.com
To: 464822504@qq.com
Message-ID: <1028214719.0.1658055006791@baby>
Subject: =?utf-8?B?6a2P6Zuo5aiH5Y+R5p2l55qE6YKu5Lu2?=
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

5LuW6K+05LuW6Ieq5bex5piv5LiqPGI+576O5aWzPC9iPg==
.
250 Mail OK queued as smtp3,DcmowAAHbp5c6dNid4fPFA--.65343S3 1658055005
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 Bye

从上面的调试信息可以看出,SMTP协议是一个请求-响应协议,客户端总是发送命令,然后等待服务器响应。服务器响应总是以数字开头,后面的信息才是用于调试的文本。这些响应码已经被定义在SMTP协议中了,查看具体的响应码就可以知道出错原因。

发送HTML邮件和文本邮件是类似的,只需要在参数中加上:

msg.setText("他说他自己是个<b>美女</b>","utf-8","html");

我们要想在电子邮件中携带附件,我们就不能直接调用message.setText()方法,而是要构造一个Multipart对象。一个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中,即可发送。

具体实现代码如下:

package com.hpc.wyj01;

import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.activation.DataHandler;
import javax.mail.BodyPart;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

public class Demo03 {
	public static void main(String[] args) {
		try {
			//1.创建Session会话
			Session session=Javacreatsession.creatSession();
			
			//2.创建邮件对象(Message抽象类的子类对象)
			MimeMessage msg=new MimeMessage(session);
			msg.setFrom(new InternetAddress("wyj000716@126.com"));
			msg.setRecipient(RecipientType.TO, new 
                           InternetAddress("464822504@qq.com"));
			msg.setSubject("魏雨娇那个傻子发来的邮件","utf-8");

			//msg.setText("他说他自己是个<b>傻子</b>","utf-8","html");
			
			//3.邮件内容“复合”对象
			Multipart multipart=new MimeMultipart();
			//正文
			//参数1:正文内容
			//参数2:内容类型;字符编码集
			BodyPart textpart=new MimeBodyPart();
			textpart.setContent("爱你孤身走<b>暗巷</b>",
                              "text/html;charset=utf-8");
			
			//附件
			BodyPart imagepart=new MimeBodyPart();
			imagepart.setFileName("sb.jpg");    //设置附件文件的显示名称
			//数据处理对象(读取附件文件从本地磁盘进行读取)
			imagepart.setDataHandler(
					new DataHandler(new ByteArrayDataSource
                              (Files.readAllBytes(Paths.get(
                                  "c:\\hpc\\QQ图片20220220101644.jpg")), 
									"application/octet-stream")));
			
			//添加至邮件内容
			multipart.addBodyPart(textpart);   //添加正文 
			multipart.addBodyPart(imagepart);   //添加附件
			//设置邮件内容
			msg.setContent(multipart);
			//发送邮件
			Transport.send(msg);
			
		} catch (AddressException e) {
			e.printStackTrace();
		} catch (MessagingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

如果我们需要将附件中的图片在正文中显示,则需要用Bodypart对象通过setHeader( )方法把Multipart添加到Message中,具体实现代码如下:

package com.hpc.wyj01;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.activation.DataHandler;
import javax.mail.BodyPart;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

import com.sun.mail.handlers.multipart_mixed;

public class Demo04 {
	public static void main(String[] args) {
		try {
			Session session=Javacreatsession.creatSession();
			
			MimeMessage message=new MimeMessage(session);
			message.setFrom(new InternetAddress("wyj000716@126.com"));
			message.setRecipient(RecipientType.TO, new 
                                 InternetAddress("464822504@qq.com"));
			message.setRecipient(RecipientType.CC, new 
                                InternetAddress("2858192496@qq.com"));
			message.setSubject("魏雨娇");
			
			Multipart multipart=new MimeMultipart();
			//2.2设置邮件内容
			//2.2.1
			//邮件正文部分
			BodyPart textpart=new MimeBodyPart();
			StringBuilder sb=new StringBuilder();
			sb.append("<h1>魏雨娇</h1>");
            //通过内容ID引用附件图片
			sb.append("<img src=\"cid:jiaozi.jpg\"/>");

			textpart.setContent(sb.toString(),"text/html;charset=utf-8");
			//邮件附件部分
			BodyPart imagepart=new MimeBodyPart();
			imagepart.setFileName("wyj.jpg");   //附件名称
			imagepart.setDataHandler(    //读取附件内容
					new DataHandler(new ByteArrayDataSource(
							Files.readAllBytes(Paths.get(
                               "c:\\hpc\\QQ图片20220220101644.jpg")),
							       "application/octet-stream")));
			
			imagepart.setHeader("Content-ID", "<jiaozi>");    //设置内容ID
			
			//组合正文+附件
			multipart.addBodyPart(textpart);    //添加正文部分
			multipart.addBodyPart(imagepart);   //添加附件部分
			
			message.setContent(multipart);
			
			Transport.send(message);
		} catch (AddressException e) {
			e.printStackTrace();
		} catch (MessagingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	

}

标签: uxr抗硫化厚膜芯片电阻

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

锐单商城 - 一站式电子元器件采购平台