java实现smtp邮件发送
一、准备工作
首先你需要已一个发送邮箱,一般的邮箱都有SMTP、POP3服务,比如QQ邮箱,登陆QQ邮箱开启SMTP服务,开启是服务器会提示你设置独立密码,这个密码是跟邮箱正常登陆的密码不同的,这个是SMTP登陆要用的密码,因此这里需记下SMTP独立密码,程序中会有使用。
(准备工作就是这么简单,只需有一个开启SMTP服务的邮箱即可);还需要一个JAR包(javax.mail.jar);java1.6里已经有了,如果没有把jar包加上。下载地址:http://www.oracle.com/technetwork/java/javamail/index-138643.html
这里贴一下QQ邮箱设置SMTP的位置:登陆邮箱------点击“设置”-------点击“账户”标签页,往下翻就可以看到如下界面
二、一般情况下发送邮件只是中间操作,所以可以使用多线程,开启一个新线程发送邮件,主程序可以继续往下执行。
1 import java.util.Properties; 2 3 import javax.mail.Authenticator; 4 import javax.mail.MessagingException; 5 import javax.mail.PasswordAuthentication; 6 import javax.mail.Session; 7 import javax.mail.Transport; 8 import javax.mail.Message.RecipientType; 9 import javax.mail.internet.InternetAddress; 10 import javax.mail.internet.MimeMessage; 11 12 public class SendMailThread extends Thread{ 13 14 private String mailAdr; 15 private String content; 16 private String subject ; 17 18 public SendMailThread(String mailAdr, String subject, String content) { 19 super(); 20 this.mailAdr = mailAdr; 21 this.content = content; 22 this.subject = subject; 23 } 24 25 @Override 26 public void run() { 27 // TODO Auto-generated method stub 28 super.run(); 29 sendMail(mailAdr,subject,content); 30 } 31 32 /* 33 * mailAdr 收件人地址 34 * subject 邮件标题 35 * content 邮件文本内容 36 */ 37 public void sendMail(String mailAdr,String subject,String content){ 38 //配置发送邮件的环境属性 39 final Properties props = new Properties(); 40 // 表示SMTP发送邮件,需要进行身份验证 41 props.put("mail.smtp.auth", "true"); 42 props.put("mail.smtp.host", "smtp.qq.com"); 43 //smtp登陆的账号、密码 ;需开启smtp登陆 44 props.put("mail.user", "XXXXX@qq.com"); 45 // 访问SMTP服务时需要提供的密码,不是邮箱登陆密码,一般都有独立smtp的登陆密码 46 props.put("mail.password", "XXXXX"); 47 48 // 构建授权信息,用于进行SMTP进行身份验证 49 Authenticator authenticator = new Authenticator() { 50 @Override 51 protected PasswordAuthentication getPasswordAuthentication() { 52 // 用户名、密码 53 String userName = props.getProperty("mail.user"); 54 String password = props.getProperty("mail.password"); 55 return new PasswordAuthentication(userName, password); 56 } 57 }; 58 59 // 使用环境属性和授权信息,创建邮件会话 60 Session mailSession = Session.getInstance(props, authenticator); 61 // 创建邮件消息 62 MimeMessage message = new MimeMessage(mailSession); 63 // 设置发件人 64 try{ 65 InternetAddress form = new InternetAddress( 66 props.getProperty("mail.user")); 67 message.setFrom(form); 68 69 // 设置收件人 70 InternetAddress to = new InternetAddress(mailAdr); 71 message.setRecipient(RecipientType.TO, to); 72 73 // 设置抄送 74 //InternetAddress cc = new InternetAddress("luo_aaaaa@yeah.net"); 75 //message.setRecipient(RecipientType.CC, cc); 76 77 // 设置密送,其他的收件人不能看到密送的邮件地址 78 //InternetAddress bcc = new InternetAddress("aaaaa@163.com"); 79 //message.setRecipient(RecipientType.CC, bcc); 80 81 // 设置邮件标题 82 message.setSubject(subject); 83 // 设置邮件的内容体 84 message.setContent(content, "text/html;charset=UTF-8"); 85 // 发送邮件 86 Transport.send(message); 87 }catch(MessagingException e){ 88 e.printStackTrace(); 89 } 90 } 91 92 public static void main(String[] args) { 93 // TODO Auto-generated method stub 94 SendMailThread d = new SendMailThread("xxxxxxx@qq.com","测试邮件标题","测试邮件001 <br>内容...."); 95 d.start(); 96 System.out.println("程序继续..."); 97 } 98 99 }
三、主程序中调用
SendMailThread mail = new SendMailThread("邮件地址","邮件标题","邮件内容"); mail.start();
//群发方式一,用数组 InternetAddress[] adds = new InternetAddress[2]; adds[0] = new InternetAddress("xxxx@qq.com"); adds[1] = new InternetAddress("xxxx@qq.com"); message.setRecipients(RecipientType.TO, adds); //群发方式二,直接用String多个地址有逗号隔开 message.setRecipients(RecipientType.TO, "xxxxx@qq.com,xxxxx@qq.com");
props.put("mail.smtp.host", "smtp.163.com");
不过,经测试发现网易的好像只能发送到网易邮箱,其他邮箱发不到,QQ邮箱就可以发送到其他任何邮箱去。
// 可以从控制台中看一下服务器的响应信息 mailSession.setDebug(true);
补充04:
上面群发的邮件是指邮件内容是相同的,群发给多个人。
另外一种情况是,多份不同的邮件群发,项目中就有遇到这种情况,群发给员工角色的邮件格式与群发给管理层角色邮件格式不同,所以自然会想到每种邮件启动一个上面代码中的线程,但是发送2种邮件还好,只需要启动两个线程,如果是100种邮件呢,会直接把JVM内存占满导致tomcat挂掉,所以应该考虑把循环都写到一个线程里面,这样只需要建立一个线程就可以完成,也节约了系统资源的占用。
在线程外面先把邮件封装好,每个邮件用一个Map来装,然后把Map再装到List里面,然后在发送邮件线程里遍历发送。
修改之后的线程如下:
1 package com.linwei.util; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.List; 6 import java.util.Map; 7 import java.util.Properties; 8 9 import javax.mail.Authenticator; 10 import javax.mail.MessagingException; 11 import javax.mail.PasswordAuthentication; 12 import javax.mail.Session; 13 import javax.mail.Transport; 14 import javax.mail.Message.RecipientType; 15 import javax.mail.internet.InternetAddress; 16 import javax.mail.internet.MimeMessage; 17 18 import org.apache.log4j.Logger; 19 20 public class SendMailThread extends Thread{ 21 22 /* 23 * @param list 24 * 存放邮件地址、标题、内容的list集合 25 * key: mailAdr,subject,content 26 */ 27 private List<Map<String,String>> list ; 28 private static final Logger log = Logger.getLogger(SendMailThread.class); 29 30 public SendMailThread(List<Map<String,String>> list){ 31 super(); 32 this.list = list ; 33 } 34 public SendMailThread(List<Map<String,String>> list,int days){ 35 super(); 36 this.list = list ; 37 } 38 39 @Override 40 public void run() { 41 // TODO Auto-generated method stub 42 super.run(); 43 if(list!=null && list.size()>0){ 44 sendMail(list); 45 } 46 } 47 48 /* 49 * mailAdr 收件人地址,多个收件地址用,隔开 50 * content 邮件文本内容 51 */ 52 public void sendMail(List<Map<String,String>> list){ 53 final Properties props = new Properties(); 54 props.put("mail.smtp.auth", "true"); 55 props.put("mail.smtp.host", "smtp.sina.com"); 56 //smtp登陆 57 props.put("mail.user", "test@sina.com"); 58 props.put("mail.password", "test123456"); 59 60 // 构建授权信息,用于进行SMTP进行身份验证 61 Authenticator authenticator = new Authenticator() { 62 @Override 63 protected PasswordAuthentication getPasswordAuthentication() { 64 // 用户名、密码 65 String userName = props.getProperty("mail.user"); 66 String password = props.getProperty("mail.password"); 67 return new PasswordAuthentication(userName, password); 68 } 69 }; 70 71 // 使用环境属性和授权信息,创建邮件会话 72 Session mailSession = Session.getInstance(props, authenticator); 73 //mailSession.setDebug(true); 74 75 try{ 76 MimeMessage message = null ; // 创建邮件消息 77 InternetAddress form = null ; //发件邮箱 78 79 log.error("***************邮件发送线程开始****************"+list.size()); 80 for(Map<String,String> map : list){ //开始遍历 81 message = new MimeMessage(mailSession); 82 form = new InternetAddress(props.getProperty("mail.user")); 83 message.setFrom(form); 84 // 设置收件人 85 message.setRecipients(RecipientType.TO, map.get("mailAdr")); // 支持群发,多地址用逗号分隔 86 // 设置邮件标题 87 message.setSubject(map.get("subject")); 88 // 设置邮件的内容体 89 message.setContent(map.get("content"), "text/html;charset=UTF-8"); 90 // 发送邮件 91 Transport.send(message); 92 } 93 }catch(MessagingException e){ 94 log.error("发送邮件出现异常!"+e.toString()); 95 e.printStackTrace(); 96 } 97 } 98 99 public static void main(String[] args) { 100 101 Map<String,String> map01 = new HashMap<String,String>(); 102 map01.put("mailAdr", "xxx@qq.com"); 103 map01.put("subject", "发送邮件方式修改测试001"); 104 map01.put("content", "abcfajglejgle"); 105 Map<String,String> map02 = new HashMap<String,String>(); 106 map02.put("mailAdr", "xxxxx@qq.com,wewe@qq.com"); 107 map02.put("subject", "发送邮件方式修改测试002"); 108 map02.put("content", "zzzzzzzzzzzzzzzzzzz"); 109 110 List<Map<String,String>> list = new ArrayList<Map<String,String>>(); 111 list.add(map01); 112 list.add(map02); 113 new SendMailThread(list).start(); 114 System.out.println("程序继续..."); 115 } 116 117 }