在Java中如何实现Emile的发送(JavaEmile)

一. 邮件
传统的邮件是通过邮局从一个邮局传递到邮局,最终到达用户的邮箱。电子邮件与之的发送过程是类似的。电子邮件是从用户电脑的邮件软件(例如:Outlook),发送到邮件服务器上,可能经过若干个邮件服务器的中转,最终到达对方邮件服务器上,收件方就可以用软件接收邮件。

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

【如何实现邮件的发送】:
就是编写一个MUA的软件,把邮件发送到MTA上。MUA到MTA发送邮件的协议就是SMTP协议。SMTP协议建立在TCP协议之上,任何程序发送邮件都必须遵守SMTP协议。(使用Java程序发送邮件时,无需关心SMTP协议的底层原理,只需要使用JavaMail这个标准API就可以直接发送)

我们把类似Outlook这样的邮件软件称为MUA。
MUA:Mail User Agent:给用户服务的邮件代理;
MTA:邮件服务器 (Mail Transfer Agent),邮件中转的代理
MDA:最终到达的邮件服务器 (Mail Delivery Agent),邮件到达的代理。

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

二.邮件协议
常见的邮件协议有:POP3,SMTP,IMAP

POP3:是Post Office Protocol 3 的简称,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件。
SMTP:全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP协议属于TCP/IP协议簇,帮助每台计算机在发送或中转信件时找到下一个目的地。
IMAP:全称是Internet Mail Access Protocol,即交互式邮件存取协议,它是跟POP3类似邮件访问标准协议之一。不同的是,开启了IMAP后,您在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端 软件登录邮箱,看到的邮件以及状态都是一致的。

IMAP和POP3有什么区别?

**·** POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮、标记已读等),不会反馈到服务器上,比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的。
**·** IMAP提供webmail与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。

1. 准备SMTP登录信息
假如我们要给王一博发送邮件,已知他的邮件地址是yibo@somewhere.com,发送邮件前,首先要确认作为MTA的邮件服务器地址和端口号。邮件服务器地址通常是smtp.example.com,端口号由邮件服务商确定使用25,465还是587。

常用邮件服务商的SMTP信息:

**·**QQ邮箱: SMTP服务器是smtp.qq.com,端口是465 / 587
**·**163邮箱:SMTP服务器是smtp.163.com,端口是465126邮箱: SMTP服务器是smtp
**.**126.com,端口是25
**.**Gmail邮箱:SMTP服务器是smtp.gmail.com,端口是465 / 587

2.准备好SMTP登录信息后,首先把JavaMail相关的依赖Jar包javax.mail-1.6.2.jar加入至当前项目。
在这里插入图片描述
①. 以126邮箱发送至QQ邮箱为例:
首先开启服务(任意一个都可以):
在这里插入图片描述
再新增授权密码:
在这里插入图片描述
二.在Java中进行邮件的发送(只包含文本)。

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

1. 创建session会话

 //  创建session会话
public class Demo01 {
	public static void main(String[] args) {
		//SMTP服务器地址
		String smtp = "smtp.126.com";
		
		//邮箱账号和密码
		String userName = "yyxxxxx@126.com";
		String password = "xxxxxxxxxxxx";
		
		//SMTP服务器的连接信息
		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
		Session session = Session.getInstance(props, new Authenticator() {
			@Override
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(userName,password);
			}
		});
		//开启调试模式
		session.setDebug(true);	
		System.out.println(session);		
	}
}

【运行结果】:
在这里插入图片描述

2.发送邮件

①. 先创建一个Session对象

Session session = JavaMailUtil.crateSession();

②. 创建邮件对象(Message抽象类的子类)

RecipientType.TO代表发送人
RecipientType.CC代表抄送人

③.创建邮件对象(Message抽象类的子类对象)

			MimeMessage msg = new MimeMessage(session); //传入session
			msg.setFrom(new InternetAddress("xxxx@126.com")); //发件人
			msg.setRecipient(RecipientType.TO, new InternetAddress("xxxxxxxx@qq.com")); // 收件人
			msg.setSubject("这是一封测试邮件", "utf-8"); // 标题

设置邮件内容 :
邮件正文中包含“html”标签(控制文本的格式)(加粗)

msg.setText("<b>moshimoshi</b> hahalou", "utf-8","html"); //正文	

注:其中发送HTML邮件和文本文件类似:
把:

message.setText(body, "UTF-8");

改成:

message.setText(body, "UTF-8", "html");

④.发送邮件

Transport.send(msg);

【整体代码实现】

JavaMailUtils类(可以循环使用):

public class JavaMailUtils {
	public static Session createSession() {
		// SMTP服务器网址
				String smtp = "smtp.126.com";
				
				//邮箱账号和密码
				String userName = "xxxx";
				String password = "xxxxxxx";
				
				// SMTP服务器的连接信息
				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	
				Session session = Session.getInstance(props, new Authenticator() {
					@Override
					protected PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication(userName, password);
					}
				});
					
				//开启调试模式
				session.setDebug(true);
				return session;			
	}
}

发送邮件

public class Demo02 {
	public static void main(String[] args) {
		try {
			// 1.创建Session会话
			Session session = JavaMailUtils.createSession();
			
			// 2.创建邮件对象(Message抽象类的子类对象)
			MimeMessage msg = new MimeMessage(session); //传入session
			msg.setFrom(new InternetAddress("xxxxx@126.com")); //发件人
			msg.setRecipient(RecipientType.TO, new InternetAddress("xxxxxxx@qq.com")); // 收件人
			msg.setSubject("这是一封测试邮件", "utf-8"); // 标题
		    
			// 邮件正文中包含“html”标签(控制文本的格式)(加粗)
			msg.setText("<b>moshimoshi</b> hahalou", "utf-8","html"); //正文
			
			// 3.发送邮件
			Transport.send(msg);		
		} catch (MessagingException e) {
			e.printStackTrace();
		}	
	}
}

3. 在Java中进行邮件的发送**(添加附件)**


我们不能直接调用message.setText()方法,而是要构造一个Multipart对象:

           // 创建MimeMessage邮件复合对象
           // .....
			Multipart multipart = new MimeMultipart();
			
			// 正文
			BodyPart textPart  =new MimeBodyPart();
			//参数1:正文内容
			//参数2:内容类型;字符编码集
			textPart.setContent("hellohellohi", "text/html;charset=utf-8");
			
			//附件
			BodyPart imagePart = new MimeBodyPart();
			imagePart.setFileName("cute.jpg");//设置附件文件的显示名称
			imagePart.setDataHandler(
					new DataHandler(
							new ByteArrayDataSource(Files.readAllBytes(Paths.get("C:\\Users\\Pictures\\Camera Roll\\IMG.JPG")),
									"application/octet-stream")));
			
			//添加至邮件内容
			multipart.addBodyPart(textPart);
			multipart.addBodyPart(imagePart);
			
			//设置邮件内容为multipart:
			msg.setContent(multipart);

一个Multipart对象可以添加若干个BodyPart,其中第一个BodyPart是文本,后面的BodyPart是附件。BodyPart依靠setContent()决定添加的内容。如果纯文本,用setContent(“xxxxx”, “text/plain;charset=utf-8”);添加纯文本;用setContent(“xxxxx”, “text/html;charset=utf-8”)添加HTML文本。
如果添加附件,需要设置文件名,并且添加一个DataHandler(),传入文件的MIME类型。二进制文件可以用application/octet-stream,Word文档则是application/msword。

【整体代码实现】

public class Demo03{
	public static void main(String[] args) {
		try {
			//1.创建Session会话
			Session session = JavaMailUtils.createSession();
			
			//2.创建邮件对象(Message抽象类的子类)
			MimeMessage msg = new MimeMessage(session);//传入session
			msg.setFrom(new InternetAddress("xxxxxx@126.com"));//发件人
			msg.setRecipient(RecipientType.TO,new InternetAddress("xxxxxx@qq.com"));
			msg.setSubject("你好呀","utf-8");
			
			//3.邮件内容
			Multipart multipart = new MimeMultipart();
			
			//正文
			BodyPart textPart  =new MimeBodyPart();
			//参数1:正文内容
			//参数2:内容类型;字符编码集
			textPart.setContent("红红火火恍恍惚惚", "text/html;charset=utf-8");
			
			//附件
			BodyPart imagePart = new MimeBodyPart();
			imagePart.setFileName("xz.jpg");//设置附件文件的显示名称
			imagePart.setDataHandler(
					new DataHandler(
							new ByteArrayDataSource(Files.readAllBytes(Paths.get("C:\\Users\\Pictures\\Camera Roll\\IMG.JPG")),
									"application/octet-stream")));
			
			//添加至邮件内容
			multipart.addBodyPart(textPart);
			multipart.addBodyPart(imagePart);
			
			//设置邮件内容
			msg.setContent(multipart);
			
			//3.发送邮件
			Transport.send(msg);		
		} catch (MessagingException | IOException e) {
			e.printStackTrace();
		}
	}
}

4 .发送内嵌图片的HTML邮件

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

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

// 创建Multipart复合对象
Multipart multipart = new MimeMultipart();
					
// 添加text:
BodyPart textpart = new MimeBodyPart();
textpart.setContent("<h1>Hello</h1><p><img src=\"cid:img01\"></p>", "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", "<img01>");

multipart.addBodyPart(imagepart);
  • 50
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值