JavaMail邮件开发

邮件开发的应用

注册,填写生日;  后期系统会自动发送生日祝贺
发货,发货提醒!邮件提醒!

邮件功能

1. 发邮件;【程序中如何发邮件!】
2. 收邮件;【很多客户端工具, foxmail  点击打开链接

邮件传输协议

SMTP协议

       全称为Simple Mail Transfer Protocol(简单邮件传输协议),它定义了邮件客户端软件与SMTP服务器之间、以及两台SMTP服务器之间的通讯规则。

POP3协议

       全称为Post Office Protocol(邮局协议),它定义了邮件客户端软件与POP3服务器的通讯规则。

IMAP协议

       全称为Internet Message Access Protocal(Internet消息访问协议),它是对POP3协议的一种扩展,定义了邮件客户端软件与IMAP服务器的通讯规则。

通过telnet命令手工发送邮件

注意:下面指令,建议直接一行一行复制(不要复制注释),这样不会出错,因为指令输错了不能修改。

  1. 手动通过163账户发送邮件的过程
  2. telnet smtp.163.com 25 //连接163邮箱smtp服务器
  3. ---------------------------------------------------以下属于smtp协议的内容
  4. ehlo lzy //向服务器打招呼
  5. auth login //请求认证,服务器提示输入用户名(zyliu1993对应enlsaXUxOTkz)和密码(Base64加密后的密码xxxxxxx为了避免您反编译破解我的密码,所以我省略)(必须是Base64编码后的)
  6. enlsaXUxOTkz
  7. xxxxxxxxxxxx //为了避免您反编译破解我的密码,所以我省略
  8. mail from:<zyliu1993@163.com> //发件人
  9. rcpt to:<1012421396@qq.com> //收件人
  10. data //说明邮件的内容开始
  11. ----------------------------------------------------以下属于邮件头
  12. from:zyliu1993@163.com
  13. to:1012421396@qq.com
  14. subject:这是2封手工发送的邮件
  15. ----------------------------------------------------注意这里必须空行
  16. //注意邮件头和邮件体必须空行,因为RFC822文档规定了邮件头和邮件体,两者使用空行分隔
  17. ---------------------------------------------------以下属于邮件体
  18. this my first email content by my hand! //邮件内容
  19. . //结束内容
  20. ---------------------------------------------------协议内容结束
  21. quit //退出
JavaMail邮件开发_第1张图片
JavaMail邮件开发_第2张图片

通过Java程序手动发送邮件

注意:我只能在debug调试模式下,一句句运行邮件才会发送,直接运行倒是不行,很奇怪。速度太快了么???
package com.cn.mail;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class MailClient {
	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("smtp.163.com", 25);//telnet smtp.163.com 25
		InputStream in = socket.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(in));// 接收服务器的反馈信息
		OutputStream out = socket.getOutputStream();//向服务器发送信息
		
		out.write("ehlo lzy\r\n".getBytes());
		System.out.println(br.readLine());
		System.out.println(br.readLine());
		System.out.println(br.readLine());
		System.out.println(br.readLine());
		System.out.println(br.readLine());
		System.out.println(br.readLine());
		System.out.println(br.readLine());
		
		out.write("auth login\r\n".getBytes());
		System.out.println(br.readLine());
		out.write("enlsaXUxOTkz\r\n".getBytes());
		System.out.println(br.readLine());
		out.write("xxxxxxxxxxxx\r\n".getBytes());//为了避免我的密码泄露,请修改xxxxxx为你的真实密码base64加密后的码值
		System.out.println(br.readLine());
		out.write("mail from:\r\n".getBytes());//这里邮箱地址必须是真实邮箱
		System.out.println(br.readLine());
		out.write("rcpt to:<[email protected]>\r\n".getBytes());
		System.out.println(br.readLine());
		out.write("data\r\n".getBytes());
		System.out.println(br.readLine());
		out.write("from:[email protected]\r\n".getBytes());//这里邮箱可以冒充
		out.write("to:[email protected]\r\n".getBytes());
		out.write("subject:手工发送的邮件\r\n".getBytes());
		out.write("\r\n".getBytes());
		out.write("大家好,我是木丁西,希望我的博文能帮到您,欢迎在博文下留言评论交流,共同进步。\r\n".getBytes());
		out.write(".\r\n".getBytes());
		socket.close();// quit
	}
}

JavaMail邮件开发_第3张图片

  邮件的传输过程
JavaMail邮件开发_第4张图片

什么是JavaMail

       要自己写程序发送和接收邮件,可以直接采用Socket编程连接上远程的邮件服务器,然后按照邮件协议与邮件服务器进行交互,涉及较多细节。另外,要想自己编程创建出复杂的MIME格式的邮件,是一件非常困难和麻烦的事情。
       JavaMail 是Sun公司为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如SMTP、POP3、IMAP。 
开发人员使用JavaMail API编写邮件处理软件时,无须考虑邮件协议的底层实施细节,只要调用JavaMail开发包中相应的API类就可以了。 
       JavaMail 也提供了能够创建出各种复杂MIME格式的邮件内容的相关API。

JavaMail API

创建和解析邮件内容的API 
       Message类是创建和解析邮件的核心API,它的实例对象代表一封电子邮件。 
发送邮件的API
       Transport类是发送邮件的核心API类,它的实例对象代表实现了某个邮件发送协议的邮件发送对象,例如SMTP协议。 
接收邮件的API
       Store类是接收邮件的核心API类,它的实例对象代表实现了某个邮件接收协议的邮件接收对象,例如POP3协议。
Session类 
       Session类用于定义整个应用程序所需的环境信息,以及收集客户端与邮件服务器建立网络连接的会话信息,如邮件服务器的主机名、端口号、采用的邮件发送和接收协议等。Session对象根据这些信息构建用于邮件收发的Transport和Store对象,以及为客户端创建Message对象时提供信息支持。 

复杂邮件内容的组织结构

1.RFC822邮件格式

2.MIME协议-MIME

       英文全称为“Multipurpose Internet Mail Extensions”,即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范,在MIME出现之前,互联网电子邮件主要遵循由RFC 822所制定的标准,电子邮件一般只用来传递基本的ASCII码文本信息,MIME在 RFC 822的基础上对电子邮件规范做了大量的扩展,引入了新的格式规范和编码方式,在MIME的支持下,图像、声音、动画等二进制文件都可方便的通过电子邮件来进行传递,极大地丰富了电子邮件的功能。目前互联网上使用的基本都是遵循MIME规范的电子邮件。  

MIME中的组合关系

JavaMail邮件开发_第5张图片

复杂邮件的组成关系

JavaMail邮件开发_第6张图片

局域网中,邮件开发准备:

准备工作, 环境搭建:
1. 本地搭建一个邮件服务器
易邮服务器,eyoumailserversetup.exe 点击打开链接
在局域网下使用这个服务器:工具->服务器设置->系统服务->“作为 局域网 邮件服务器”->单域名,随便设置(比如lzy.com)
2. 默认的邮箱账号:[email protected]
新建邮箱账号
例如账号:zhangsan
密码:888888
此邮箱账号即为:[email protected]
例如账号:lisi
密码:666666
此邮箱账号即为:[email protected]
3. 安装foxmail
配置邮件发送服务器(smtp):localhost 端口号25
邮件接收服务器(pop3):localhost  端口号110
然后刚刚注册的账号,就能在本地局域网中发送邮件了。

JavaMail开发步骤

在java项目中引入jar文件 点击打开链接
activation.jar   【(注意:Javamail的API依赖jaf(Java Activation Framework)框架,还需要导入jaf的jar包。如果使用的是JDK6及以上版本,就不需要了,但是加上为妙)】
mail.jar       【邮件发送核心包】
注意:如果是web项目,因为javaee自带的有邮件功能,可能存在问题!我们要用自己的mail.jar文件功能!需要删除javaee中mail包!

案例:

需求:

1.发送一封普通邮件
2.发送带图片资源的邮件
3.发送带图片资源和附件的邮件

java项目结构

JavaMail邮件开发_第7张图片

Java代码

package com.cn.mail;
import java.io.File;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message.RecipientType;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.junit.Test;
/**
* Author:Liu Zhiyong(QQ:1012421396)
* Version:Version_1
* Date:2017年5月6日21:29:16
* Desc:发送邮件,局域网下,使用自己的邮箱服务器写的案例
*/
public class SendMail {
	//初始化参数
	private static Properties properties;
	private static InternetAddress sender;
	private String filePath;
	//发件人
	static{
		properties = new Properties();
		properties.put("mail.transport.protocol", "smtp");//指定协议
		properties.put("mail.smtp.host", "localhost");//主机 stmp.qq.com
		properties.put("mail.smtp.port", 25);//端口
		properties.put("mail.smtp.auth", "true");//用户密码验证
		properties.put("mail.debug", "true");//调试模式
		try {
			sender = new InternetAddress("[email protected]");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 发送一封普通邮件
	 * @throws Exception
	 */
	@Test
	public void testSendMail() throws Exception {
		
		//1.创建包含邮件服务器的网络连接信息的Session会话对象
		Session session = Session.getDefaultInstance(properties);
		//2.创建代表邮件内容的Message对象(整封邮件对象)
		MimeMessage message = new MimeMessage(session);
		//3.设置邮件体参数
		message.setSubject("木丁西([email protected])的发送的邮件邮件");//邮件标题
		message.setSentDate(new Date());//邮件发送时间
		message.setSender(new InternetAddress("[email protected]"));//发件人
		message.setRecipient(RecipientType.TO, new InternetAddress("[email protected]"));//收件人
//		message.setText("邮件正文。。。。hello this is my first mail to you !");//简单纯文本邮件
		message.setContent("百度", "text/html;charset=utf-8");//发送超链接
		
		message.saveChanges();//保存邮件(可选)
		
		//4.创建Transport对象
		Transport trans = session.getTransport();
		//5.连接服务器
		trans.connect("mdx", "mdx");//注意这里是发件人的用户名和密码
		//6.发送邮件
		trans.sendMessage(message, message.getAllRecipients());
		//7.关闭连接
		trans.close();
		
	}
	
	/**
	 * 发送带图片资源的邮件
	 * @throws Exception
	 */
	@Test
	public void testSendMailWithImage() throws Exception {
		//1.创建邮件会话
		Session session = Session.getDefaultInstance(properties);
		//2.创建邮件对象
		MimeMessage message = new MimeMessage(session);
		//3.设置参数:标题、发件人、收件人、发送时间、内容
		message.setSubject("发送带图片资源的邮件");
		message.setSender(sender);
		message.setRecipient(RecipientType.TO, new InternetAddress("[email protected]"));
		message.setSentDate(new Date());
		
		//4.设置发送内容:多功能用途邮件(related)
//		message.setContent("", "text/html;charset=utf-8");
		//4.1构建一个多功能邮件块
		MimeMultipart related = new MimeMultipart("related");
		//4.2构建多功能邮件块内容=文本+图片资源
		MimeBodyPart content = new MimeBodyPart();
		MimeBodyPart resource = new MimeBodyPart();
		//4.3设置具体内容:文本
		content.setText("这里是普通文本内容");
		//4.4设置具体内容:a.资源(图片)
//		String filePath = SendMail.class.getResource("hh.png").getPath();//类路径获取资源文件路径,但是路径中有空格或者中文等特殊字符会乱码,导致路径不对
		/**
		 * 解决方式1:
		 */
//		filePath = filePath.replace("%20", " ");//路径中的空格为20%,所以也可以用空格进行字符串替换,但是对中文乱码又无法解决
		/**
		 * 解决方式2:
		 */
//		String filePath = SendMail.class.getResource("hh.png").getPath();
//		filePath = URLDecoder.decode(filePath, "gbk");//只能解决一部分,若路径中含有+,也是不能解决的,原因是URL并不是完全用URLEncoder.encode(str,"UTF-8")编码的,+号被解码后,却变成了空格。
		/**
		 * 解决方式3:(推荐)
		 */
		String filePath = SendMail.class.getResource("hh.png").toURI().getPath();
		System.out.println(".........................." + filePath);
		
		FileDataSource ds = new FileDataSource(new File(filePath));
		DataHandler handler = new DataHandler(ds);
		resource.setDataHandler(handler);
		resource.setContentID("hh.png");//设置资源名称给外界引用,可以随便取名
		//设置具体内容:b.文本
		content.setContent(" 我长得帅吗????哈哈哈","text/html;charset=utf-8");
		
		related.addBodyPart(content);
		related.addBodyPart(resource);
		//4.5 把构建的复杂邮件块,添加到邮件中
		message.setContent(related);
		
		//5.创建Transport对象
		Transport trans = session.getTransport();
		//6.连接服务器
		trans.connect("mdx", "mdx");//注意这里是发件人的用户名和密码
		//7.发送邮件呢
		trans.sendMessage(message, message.getAllRecipients());
		//8.关闭连接
		trans.close();
	}
	
	/**
	 * 发送带图片资源和附件的邮件
	 * @throws Exception
	 */
	@Test
	public void testSendMailWithImageAndAttachment() throws Exception {
		//1.创建邮件会话
		Session session = Session.getDefaultInstance(properties);
		//2.创建邮件对象
		MimeMessage message = new MimeMessage(session);
		//3.设置参数:标题、发件人、收件人、发送时间、内容
		message.setSubject("发送带图片资源的邮件");
		message.setSender(sender);
		message.setRecipient(RecipientType.TO, new InternetAddress("[email protected]"));
		message.setSentDate(new Date());
		/************************************带附件邮件功能开发**********************************************/
		//构建一个总的邮件块
		MimeMultipart mixed = new MimeMultipart("mixed");
		//总邮件块设置到邮件对象中
		message.setContent(mixed);
		//左侧:(文本+图片资源)
		MimeBodyPart left = new MimeBodyPart();
		//右侧:附件
		MimeBodyPart right = new MimeBodyPart();
		
		//设置到总邮件块中
		mixed.addBodyPart(left);
		mixed.addBodyPart(right);
		
		/********************************附件***************************************************/
		String attachmentFile = this.getClass().getResource("../../../a.zip").toURI().getPath();
		System.out.println("。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。" + attachmentFile);
		FileDataSource ds = new FileDataSource(new File(attachmentFile));
		DataHandler attachmentHandler = new DataHandler(ds);
		right.setDataHandler(attachmentHandler);
		right.setFileName("a.zip");//注意这里的名字,应该和附件名一样,特别是其后缀。
		
		
		/************************************设置发送内容:多功能用途邮件(related)**********************************************/
		//4.设置发送内容:多功能用途邮件(related)
//		message.setContent("", "text/html;charset=utf-8");
		//4.1构建一个多功能邮件块
		MimeMultipart related = new MimeMultipart("related");
		//设置到总邮件块的左侧中
		left.setContent(related);
		//4.2构建多功能邮件块内容=文本+图片资源
		MimeBodyPart content = new MimeBodyPart();
		MimeBodyPart resource = new MimeBodyPart();
		//4.3设置具体内容:文本
		content.setText("这里是普通文本内容");
		//4.4设置具体内容:a.资源(图片)
//		String filePath = SendMail.class.getResource("hh.png").getPath();//类路径获取资源文件路径,但是路径中有空格或者中文等特殊字符会乱码,导致路径不对
		/**
		 * 解决方式1:
		 */
//		filePath = filePath.replace("%20", " ");//路径中的空格为20%,所以也可以用空格进行字符串替换,但是对中文乱码又无法解决
		/**
		 * 解决方式2:
		 */
//		String filePath = SendMail.class.getResource("hh.png").getPath();
//		filePath = URLDecoder.decode(filePath, "gbk");//只能解决一部分,若路径中含有+,也是不能解决的,原因是URL并不是完全用URLEncoder.encode(str,"UTF-8")编码的,+号被解码后,却变成了空格。
		/**
		 * 解决方式3:(推荐)
		 */
		String filePath = SendMail.class.getResource("hh.png").toURI().getPath();
		
		FileDataSource ds2 = new FileDataSource(new File(filePath));
		DataHandler handler = new DataHandler(ds2);
		resource.setDataHandler(handler);
		resource.setContentID("hh.png");//设置资源名称给外界引用,可以随便取名
		//设置具体内容:b.文本
		content.setContent(" 我长得帅吗????哈哈哈","text/html;charset=utf-8");
		
		related.addBodyPart(content);
		related.addBodyPart(resource);
		
		//5.创建Transport对象
		Transport trans = session.getTransport();
		//6.连接服务器
		trans.connect("mdx", "mdx");//注意这里是发件人的用户名和密码
		//7.发送邮件呢
		trans.sendMessage(message, message.getAllRecipients());
		//8.关闭连接
		trans.close();
	}
	
}

互联网中发送邮件(普通文本+图片+附件)

package com.cn.mail;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message.RecipientType;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.junit.Before;
import org.junit.Test;

public class MailDemo {
	private Properties properties;//环境变量设置,发送邮件时才需要,若是只保存本地,则不需要
	
	@Before
	public void testPrepare() throws Exception {
		properties = new Properties();
		properties.put("mail.transport.protocol", "smtp");//发送邮件使用的协议smtp
		properties.setProperty("mail.host", "smtp.163.com");//发送服务器的主机地址
		properties.put("mail.smtp.port", 25);//端口,可省略
		properties.setProperty("mail.smtp.auth", "true");//请求身份验证
		properties.setProperty("mail.debug", "true");//调试模式
	}
	
	@Test
	public void testSendMail() throws Exception {
		
		//创建包含邮件服务器的网络连接信息的Session会话对象
		Session session = Session.getDefaultInstance(properties);
		MimeMessage message = new MimeMessage(session);//代表一封邮件
		
		message.setSender(new InternetAddress("[email protected]"));//设置发件人
		message.setRecipients(RecipientType.TO, "[email protected]");//设置收件人
		message.setSubject("我的邮件主题");//设置邮件主题
		
		//文本和超文本部分
		MimeBodyPart  textHypertextPart = new MimeBodyPart();
		textHypertextPart.setContent("there is 正文内容哟. 超链接", "text/html;charset=utf-8");//这里cid是指资源的ContentID
		
		//内嵌图片部分
		MimeBodyPart imagePart = new MimeBodyPart();
		//把磁盘上的文件读到邮件上来:借助JAF框架
		String path = this.getClass().getResource("hh.png").toURI().getPath();
		DataHandler handler1 = new DataHandler(new FileDataSource(new File(path)));
		imagePart.setDataHandler(handler1);
		imagePart.setContentID("hh");
		
		//描述imagePart和textPart两者关系:文本和内嵌图片合体related
		MimeMultipart multipart1 = new MimeMultipart();
		multipart1.addBodyPart(textHypertextPart);
		multipart1.addBodyPart(imagePart);
		multipart1.setSubType("related");//说明两部分是有关系的
		
		MimeBodyPart textImagePart = new MimeBodyPart();
		textImagePart.setContent(multipart1);
		
		//附件部分
		MimeBodyPart attachmentPart = new MimeBodyPart();
		DataHandler handler2 = new DataHandler(new FileDataSource(this.getClass().getResource("../../../abc附件.zip").toURI().getPath()));
		String fileName = handler2.getName();//获取文件2名
		attachmentPart.setDataHandler(handler2);
		attachmentPart.setFileName(MimeUtility.encodeText(fileName));//手工设置文件名,中文文件名要注意编码
		
		//全部合体
		MimeMultipart multipart = new MimeMultipart();
		multipart.addBodyPart(textImagePart);//文件加内嵌图片
		multipart.addBodyPart(attachmentPart);//附件
		multipart.setSubType("mixed");//复杂关系
		
		//设置邮件内容主体
		message.setContent(multipart);
//		message.saveChanges();//这个可写可不写
		
		message.writeTo(new FileOutputStream(new File("d:/2.eml")));//把邮件存到本地磁盘上
		
		//获取Transport对象
		Transport trans = session.getTransport();
		//连接服务器
		trans.connect("zyliu1993", "xxxxxx");//注意这里的密码XXXXX是163邮箱的授权码用户名zyliu1993或者邮箱[email protected]都行
		//发送邮件
		trans.sendMessage(message, message.getAllRecipients());//发送邮件给所有收件人
		
		//关闭
		trans.close();
	}	
	
	@Test
	public void testDemo() throws Exception {
		properties.setProperty("mail.transport.protocol", "smtp");//发送使用的协议
		properties.setProperty("mail.host", "smtp.163.com");//发送服务器的主机地址
		properties.setProperty("mail.smtp.auth", "true");//请求身份验证
		Session session = Session.getDefaultInstance(properties);
		MimeMessage message = new MimeMessage(session);//代表一封邮件
		
		message.setFrom(new InternetAddress("[email protected]"));//设置发件人
		message.setRecipients(RecipientType.TO, "[email protected]");//设置收件人
		message.setSubject("这是JavaMail发出的第一封邮件");//设置主体
		
		//设置邮件的正文内容
		message.setText("嘿嘿!JavaMail发送的邮件哦");
		message.saveChanges();
		//发送邮件
		Transport ts = session.getTransport();//得到火箭
		ts.connect("zyliu1993","XXXX");//连接,注意这里的密码XXXXX是163邮箱的授权码
		ts.sendMessage(message, message.getAllRecipients());
		
		ts.close();
	}
}
JavaMail邮件开发_第8张图片
附加:设置自定义发件人昵称
//设置自定义发件人昵称  
String nick=javax.mail.internet.MimeUtility.encodeText("荆韵书香商城系统");//对中文进行编码  
message.setFrom(new InternetAddress(nick+""));//后面的发件人地址必须加,还必须对
JavaMail邮件开发_第9张图片

你可能感兴趣的:(servlet)