java发送mail邮件

在介绍之前,先说一下注意事项

如果是连接的公司内部的局域网,那么最好连接公司自己搭建的邮件服务器;如果连接外部的邮件服务器,那么可能会失败(此时可以通过断开公司内部局域网,转而连接广域网来解决问题)

测试发送邮件时,不要发送太简单的邮件,因为有的你连接的邮件服务器可能具备检测功能,如果你发的邮件太简单,那么就会被检测到,不予发送;用时consule打印出504等错误

发送邮件时,明明这边发送成功,但是对方却没有收到;这也是因为邮件过于简单,被对方的邮箱检测出了,可能放进垃圾箱中了

下面正式介绍java发送邮件:

第一步:编写身份验证类

import javax.mail.Authenticator;

/**
 * 通过账号密码(或账号授权码)进行身份验证
 */
public class MailAuthenticator extends Authenticator {
	
	/** 邮箱号[email protected] */
	private String userName;
	
	/**
	 * 邮箱密码或授权码(不同邮箱可能不一样,如163邮箱的话,就是授权码)
	 */
	private String password;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public MailAuthenticator(String username, String password) {
		this.userName = username;
		this.password = password;
	}
}


第二步:编写邮件发送具体逻辑、以及对外提供发送邮件的方法

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

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.Multipart;
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;

public class SendMail {

	/** 身份验证实体类模型工具 */
	public static MailAuthenticator authenticator;

	/**
	 * Message对象,用于封装要发送的邮件信息
	 */
	private MimeMessage message;

	/** 会话 */
	private Session session;

	/** Transport对象,用于执行邮件的发送任务 */
	private Transport transport;

	/**
	 * 参数信息 
	 * 注:我们也可以创建.properties文件,然后将配置信息写到该文件中, 这样一来就不需要new Properties()对象了
	 */
	private Properties properties = new Properties();

	/** 要连接的邮件服务器(如:SMTP、IMAP、POP3等) */
	private String mailHost = null;

	/** 发送人邮箱 */
	private String sender_mail = null;

	/**
	 * 密码(或 授权码) 注:163邮箱使用的是授权码
	 */
	private String sender_password = null;
	
	/** 发送者的别名(注:收邮件会显示的 由  此名字发送给他的) */
	private String sender_alias = null;
			

	/**
	 * 初始化smtp发送邮件所需参数
	 *
	 * @return
	 * @date 2018年7月4日 下午7:40:14
	 */
	private boolean initSmtpParams() {
		// 发送者的邮箱
		sender_mail = "[email protected]";

		// 密码(或 授权码) 163邮箱是授权码
		sender_password = "xxxxxx";
		
		// 发送者的别名(注:收邮件会显示的 由  此名字发送给他的)
		sender_alias = "邓沙利文";

		// 要连接的SMTP服务器
		mailHost = "smtp.163.com";
		properties.put("mail.smtp.host", mailHost);

		// 是否开启身份验证
		properties.put("mail.smtp.auth", "true");
		
		// 发送邮件协议名称
		properties.put("mail.transport.protocol", "smtp");

		// 是否将纯文本连接升级为加密连接(TLS或SSL)
		// starttls主要针对于IMAP和POP3,本例使用过的是SMTP
		properties.put("mail.smtp.starttls.enable", "true");

		// 不做服务器证书校验
		properties.put("mail.smtp.ssl.checkserveridentity", "false");

		// 添加信任的服务器地址,多个地址之间用空格分开
		properties.put("mail.smtp.ssl.trust", mailHost);

		// 要连接的SMTP服务器的端口号(默认值为25)
		properties.put("mail.smtp.port", "25");

		// 指定 套接字工厂 要连接到的端口
		properties.put("mail.smtp.socketFactory.port", "25");

		// 如果设置为true,未能创建自己指定的套接字时将使用java.net.Socket创建的套接字类。默认为true
		properties.put("mail.smtp.socketFactory.fallback", "false");

		// 设置套接字连接超时值(单位毫秒) 默认不超时
		properties.put("mail.smtp.connectiontimeout", "10000");

		// Socket I/O超时值(单位毫秒) 缺省值不超时
		properties.put("mail.smtp.timeout", "10000");

		// 根据账号,授权码(或密码)进行身份验证
		authenticator = new MailAuthenticator(sender_mail, sender_password);

		// 获取session实体对象
		session = Session.getInstance(properties, authenticator);

		// 开启调试信息
		session.setDebug(true);

		// 获取message实体对象
		message = new MimeMessage(session);
		return true;
	}

	/**
	 * 供外界调用的发送邮件接口(里面初始化了参数 并 调用了真正发送邮件的方法)
	 */
	public boolean sendEmail(String title, String content, List<String> receivers,
			List<String> ccReceivers, List<String> bccReceivers, List<File> fileList) {
		try {
			// 初始化smtp发送邮件所需参数
			initSmtpParams();
			// 发送邮件
			doSendHtmlEmail(title, content, receivers, ccReceivers, bccReceivers, fileList);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * 发送邮件
	 */
	private boolean doSendHtmlEmail(String title, String htmlContent, 
			List<String> receivers, List<String> ccReceivers, 
			List<String> bccReceivers, List<File> fileList) {
		try {
			// 发件人邮箱、别名
			InternetAddress from = new InternetAddress(sender_mail,sender_alias);
			message.setFrom(from);

			// 直接收件人TO(多个),即:发送
			if(receivers == null)
				return false;
			InternetAddress[] sendTo = new InternetAddress[receivers.size()];
			for (int i = 0; i < receivers.size(); i++) {
				sendTo[i] = new InternetAddress(receivers.get(i));
			}
			// 发送
			message.setRecipients(MimeMessage.RecipientType.TO, sendTo);
			
			// 间接收件人CC(多个),即:抄送
			// 抄送:即除了发给直接目标外,还将邮件发给其他人(这些人可以看见邮件都发给了谁)
			if(ccReceivers != null) {
				InternetAddress[] sendCc = new InternetAddress[ccReceivers.size()];
				for (int i = 0; i < ccReceivers.size(); i++) {
					sendCc[i] = new InternetAddress(ccReceivers.get(i));
				}
				// 抄送
				message.setRecipients(MimeMessage.RecipientType.CC, sendCc);
			}
			
			// 间接收件人BCC(多个),即:密送
			// 密送:即除了发给直接目标外,还将邮件发给其他人(这些人看不见:除了直接接受者外邮件还发给了谁)
			if(bccReceivers != null) {
				InternetAddress[] sendBcc = new InternetAddress[bccReceivers.size()];
				for (int i = 0; i < bccReceivers.size(); i++) {
					sendBcc[i] = new InternetAddress(bccReceivers.get(i));
				}			
			// 密送
			message.setRecipients(MimeMessage.RecipientType.BCC, sendBcc);
			}
			
			// 邮件主题
			message.setSubject(title);

			// 添加邮件的各个部分内容,包括文本内容和附件
			Multipart multipart = new MimeMultipart();

			// 添加邮件正文
			BodyPart contentPart = new MimeBodyPart();
			// 设置邮件内容板式(这里为html)、编码为utf8
			// 提示:因为这里是html,所以我们可以通过html元素等来修饰邮件内容,包括<br>换行、css样式之类的
			contentPart.setContent(htmlContent, "text/html;charset=UTF-8");
			multipart.addBodyPart(contentPart);

			// 遍历添加附件
			if (fileList != null && fileList.size() > 0) {
				for (File file : fileList) {
					BodyPart attachmentBodyPart = new MimeBodyPart();
					DataSource source = new FileDataSource(file);
					attachmentBodyPart.setDataHandler(new DataHandler(source));
					attachmentBodyPart.setFileName(file.getName());
					multipart.addBodyPart(attachmentBodyPart);
				}
			}

			// 将multipart对象放到message中
			message.setContent(multipart);

			// 保存邮件
			message.saveChanges();

			// SMTP验证
			transport = session.getTransport("smtp");
			transport.connect(mailHost, sender_mail, sender_password);

			// 发送邮件
			transport.sendMessage(message, message.getAllRecipients());

			System.out.println(title + "发送成功!");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (transport != null) {
				try {
					transport.close();
				} catch (MessagingException e) {
					e.printStackTrace();
				}
			}
		}
		return true;
	}
}

第三步:测试一下

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Test {
	/**
	 * 测试一下
	 *
	 * @param args
	 * @date 2018年7月4日 下午8:17:11
	 */
	public static void main(String[] args) {
		// 邮件主题
		String title = "java代码发送mail";

		// 邮件正文
		String htmlContent = "<span style='color:red;'>我是一只小小鸟,咿呀咿呀哟~!</span>";

		// 收件人
		List<String> receivers = new ArrayList<String>();
		receivers.add("[email protected]");
		
		// 抄送人
		List<String> ccReceivers = new ArrayList<String>();
		ccReceivers.add("[email protected]");
		ccReceivers.add("[email protected]");
		
				
		// 密送人
		List<String> bccReceivers = new ArrayList<String>();
		bccReceivers.add("[email protected]");
		bccReceivers.add("[email protected]");
		

		// 附件
		String fileName1 = "C:\\Users\\JustryDeng\\Desktop\\file\\Eclipse插件编写54218.docx";
		File file1 = new File(fileName1);
		String fileName2 = "C:\\Users\\JustryDeng\\Desktop\\file\\hosts21441";
		File file2 = new File(fileName2);
		List<File> fileList = new ArrayList<File>();
		fileList.add(file1);
		fileList.add(file2);
		// 执行发送(带附件)
		// new SendMail().sendEmail(title, htmlContent, receivers, ccReceivers, bccReceivers, fileList);
		// 执行发送(无附件)
		new SendMail().sendEmail(title, htmlContent, receivers, ccReceivers, bccReceivers, null);
	}
}

运行之后,console打印出:

运行之后,可以收到邮件:

注:发邮件时,会自动去除TO类型中的重复的邮箱地址;去除CC、BCC中的重复的邮箱地址。即:去重时,将TO归为一个模块儿去  重,将CC和BCC这两个归为一个模块儿进行去重。

微笑代码托管链接https://github.com/JustryDeng/PublicRepository

微笑这是我以前做的笔记,这次加了点新的内容;以前做此笔记时,参考了好几个人的      博客资料等,具体的我记不得了,如若涉及到侵权问题,请联系我。

微笑如有不当之处,欢迎指正

微笑本文已经被收录进《程序员成长笔记(二)》,作者JustryDeng

猜你喜欢

转载自blog.csdn.net/justry_deng/article/details/80918387