资讯详情

Java Email-----使用Java程序实现收发电子邮件

前言:完成使用Java在收发电子邮件之前,让我们来看看传统邮件是如何发送的:传统邮件是通过邮局发送的,然后从一个邮局到另一个邮局,最后到达用户的邮箱。

           ┌──────────┐    ┌──────────┐            │PostOffice│    │PostOffice│     .───. ┌─────┐    ├──────────┤    ├──────────┤    (   ( ) │═══ ?│───>│ ┌─┐ ┌┐┌┐ │───>│ ┌─┐ ┌┐┌┐ │───> `─┬─' └─────┘    │ │?│ └┘└┘ │    │ │?│ └┘└┘ │       │            └─┴─┴──────┘    └─┴─┴──────┘       │

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

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

理解几个概念:

MUA:Mail User Agent邮件代理(邮件软件)为用户服务

MTA:Mail Transfer Agent 邮件中转代理(邮件服务器)

MDA:Mail Delivery Agent代理邮件到达(最终到达的邮件服务器)

一旦电子邮件到达MDA,不再动了。事实上,电子邮件通常存储在MDA在服务器硬盘上,等待收件人通过软件或登录浏览器查看电子邮件。

准备SMTP登录信息

在发送邮件之前,我们必须首先确定它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通信的详细内容便于调试。

我们把获取Session实例代码包装在JavaMailUtils作为一种创造Session通过静态方法对象的工具类creatSession()方便我们快速创建Session对象。实现代码如下:

public class JavaMailUtils {  public static Session creatSession() {   // 服务器地址:     String smtp = "smtp.126.com";      // 登录用户名:     String username = "xxxxxxxxxxxx@126.com";      // 登录口令:     String password = "xxxxxxxxxxxxxxxxxxxx";      // 连接到SMTP服务器25端口:     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() {         protected PasswordAuthentication getPasswordAuthentication() {             return new PasswordAuthentication(username, password);         }     });     // 设置debug调试方便:     session.setDebug(true);     return session;  }  } 

发送邮件

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

try {    Session session = JavaMailUtils.creatSession();       MimeMessage message = new MimeMessage(session);       // 设置发送方地址:       message.setFrom(new InternetAddress("xxxxxxxxxxxxxx@126.com"));       // 设置接收方地址:       TO主要收件人 CC抄送人       message.setRecipient(Message.RecipientType.TO, new InternetAddress("xxxxxxxxxxxxx@qq.com"));       // 设置邮件主题:       message.setSubject("这是一封测试邮件", "UTF-8");       // 设置邮件文本:       message.setText("<b>爱你</b>孤身走暗巷...", "UTF-8","html");////邮件正文包含在邮件正文中"html"标签(控制文本格式)                   // 发送:       Transport.send(message);   } catch (AddressException e) {       e.printStackTrace();   } catch (MessagingException e) {       e.printStackTrace();   } catch (IOException 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=Lenovo, 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 LAPTOP-DMM2VL3R.mshome.net 250-mail 250-PIPELINING 250-AUTH LOGIN PLAIN XOAUTH2 250-AUTH=LOGIN PLAIN XOAUTH2 250-coremail 1Uxr2xKj7kG0xkI7xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFvE1abUCa0xDrUUUUj
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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFvE1abUCa0xDrUUUUj"
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-DMM2VL3R.mshome.net
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN XOAUTH2
250-AUTH=LOGIN PLAIN XOAUTH2
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrxbFmDUCa0xDrUUUUj
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 "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UrxbFmDUCa0xDrUUUUj"
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=tyqiqiiqiii@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:<tyqiqiiqiii@126.com>
250 Mail OK
RCPT TO:<1601671085@qq.com>
250 Mail OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   1601671085@qq.com
DATA
354 End data with <CR><LF>.<CR><LF>
Date: Sun, 17 Jul 2022 16:58:47 +0800 (CST)
From: tyqiqiiqiii@126.com
To: 1601671085@qq.com
Message-ID: <2128227771.0.1658048327389@LAPTOP-DMM2VL3R.mshome.net>
Subject: =?UTF-8?B?6L+Z5piv5LiA5bCB5rWL6K+V6YKu5Lu2?=
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64

PGI+54ix5L2gPC9iPuWtpOi6q+i1sOaal+W3ty4uLg==
.
250 Mail OK queued as smtp1,C8mowACHnydGz9NieECmGw--.58834S3 1658048329
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 Bye

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

发送附件

要在电子邮件中携带附件,我们就不能直接调用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中,即可发送。

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

// 创建Multipart复合对象
Multipart multipart = new MimeMultipart();

// 添加text:
BodyPart textpart = new MimeBodyPart();
textpart.setContent(body, "text/html;charset=utf-8");
multipart.addBodyPart(textpart);

// 添加image:
BodyPart imagepart = new MimeBodyPart();
imagepart.setFileName(附件名称);
imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(文件流字节数组, "application/octet-stream")));
multipart.addBodyPart(imagepart);

// 设置邮件内容为multipart:
message.setContent(multipart);

发送内嵌图片的HTML邮件

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

 

//邮件内容"复合"对象
		    Multipart multipart=new MimeMultipart();
		    //正文
		    BodyPart textPart = new MimeBodyPart();
		    StringBuilder body=new StringBuilder();
		    body.append("<h1>猫</h1>");
		    body.append("<img src=\"cid:cat\"/>");//通过内容id引用附件图片
		    //参数1:正文内容
		   //参数2:内容类型;字符编码集
		    textPart.setContent(body.toString(),"text/html;charset=utf-8");
		    
		    //附件
		    BodyPart imagePart = new MimeBodyPart();
		    imagePart.setFileName("cat.jpg");//设置附件文件的显示名称
		    //数据处理对象(读取附件文件从本地磁盘进行读取)
		    imagePart.setDataHandler(new DataHandler(new ByteArrayDataSource(Files.readAllBytes(Paths.get("E:\\picture\\8504221.jpg")), "application/octet-stream")));
		    imagePart.setHeader("Content-ID","<cat>");//设置内容id
		    //添加至邮件内容
		    multipart.addBodyPart(textPart);//添加正文
		    multipart.addBodyPart(imagePart);//添加附件
		    
		    //设置邮件内容
		    message.setContent(multipart);
		    

以上是最近学习中收获知识的一点小总结,如果对你有帮助,请留下你的点赞和关注,谢谢! 

标签: 固态电容ulguxr抗硫化厚膜芯片电阻

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

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