javamail实现用普通QQ邮箱发送邮件

今天药忘吃喽~ 2022-08-22 00:27 374阅读 0赞

本人最近在写一个Android项目,用户注册的时候想用邮箱验证的方式,于是就需要在服务器端发送电子邮件给新注册用户,邮件内容中包含一个 链接, 当用户点击这个链接将 登录到服务器 的验证逻辑。本人在网上找了很多代码,可能由于是很久以前的了,各大邮箱的规范 什么的都发生改变,所以总是出现一些问题。庆幸 的是,最后还是实现了。

这是我用大号 发给小号 和另外一个 163 邮箱的 测试邮件
这里写图片描述

首先,发一个连接,我在困扰了了两天之后,终于得到了这位前辈的解救,我发的代码基本上也都是他的源码,只是有几处关键地方的改动。
点击
当然,把前辈的代码 copy 直接运行肯定是不行的。
废话不说,直接上源码吧:

1、发送邮件的类:

  1. package com.pleasurewithriding.assistantclass;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.io.UnsupportedEncodingException;
  5. import java.util.Date;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Properties;
  9. import javax.activation.DataHandler;
  10. import javax.activation.DataSource;
  11. import javax.activation.FileDataSource;
  12. import javax.mail.Address;
  13. import javax.mail.Authenticator;
  14. import javax.mail.BodyPart;
  15. import javax.mail.Message;
  16. import javax.mail.MessagingException;
  17. import javax.mail.Multipart;
  18. import javax.mail.PasswordAuthentication;
  19. import javax.mail.Session;
  20. import javax.mail.Transport;
  21. import javax.mail.internet.AddressException;
  22. import javax.mail.internet.InternetAddress;
  23. import javax.mail.internet.MimeBodyPart;
  24. import javax.mail.internet.MimeMessage;
  25. import javax.mail.internet.MimeMultipart;
  26. import javax.mail.internet.MimeUtility;
  27. public class SendMail {
  28. private String username = null;
  29. private String password = null;
  30. private Authenticator auth = null;
  31. private MimeMessage mimeMessage =null;
  32. private Properties pros = null;
  33. private Multipart multipart = null;
  34. private BodyPart bodypart= null;
  35. /** * 初始化账号密码并验证 * 创建MimeMessage对象 * 发送邮件必须的步骤:1 * @param username * @param password */
  36. public SendMail(String username,String password){
  37. this.username = username;
  38. this.password = password;
  39. }
  40. /** * 初始化MimeMessage对象 * 发送邮件必须的步骤:3 */
  41. public void initMessage(){
  42. this.auth = new Email_Autherticator();
  43. Session session = Session.getDefaultInstance(pros,auth);
  44. session.setDebug(true); //设置获取 debug 信息
  45. mimeMessage = new MimeMessage(session);
  46. }
  47. /** * 设置email系统参数 * 接收一个map集合key为string类型,值为String * 发送邮件必须的步骤:2 * @param map */
  48. public void setPros(Map<String,String> map){
  49. pros = new Properties();
  50. for(Map.Entry<String,String> entry:map.entrySet()){
  51. pros.setProperty(entry.getKey(), entry.getValue());
  52. }
  53. }
  54. /** * 验证账号密码 * 发送邮件必须的步骤 * @author Administrator * */
  55. public class Email_Autherticator extends Authenticator {
  56. public PasswordAuthentication getPasswordAuthentication()
  57. {
  58. return new PasswordAuthentication(username, password);
  59. }
  60. }
  61. /** * 设置发送邮件的基本参数(去除繁琐的邮件设置) * @param sub 设置邮件主题 * @param text 设置邮件文本内容 * @param rec 设置邮件接收人 * @throws MessagingException * @throws UnsupportedEncodingException */
  62. public void setDefaultMessagePros(String sub,String text,String rec) throws MessagingException, UnsupportedEncodingException{
  63. mimeMessage.setSubject(sub);
  64. mimeMessage.setText(text);
  65. mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(rec));
  66. mimeMessage.setSentDate(new Date());
  67. mimeMessage.setFrom(new InternetAddress(username,username));
  68. }
  69. /** * 设置主题 * @param subject * @throws MessagingException */
  70. public void setSubject(String subject) throws MessagingException{
  71. mimeMessage.setSubject(subject);
  72. }
  73. /** * 设置日期 * @param date * @throws MessagingException */
  74. public void setDate(Date date) throws MessagingException{
  75. mimeMessage.setSentDate(new Date());
  76. }
  77. /** * 设置邮件文本内容 * @param text * @throws MessagingException */
  78. public void setText(String text) throws MessagingException{
  79. mimeMessage.setText(text);
  80. }
  81. /** * 设置邮件头部 * @param arg0 * @param arg1 * @throws MessagingException */
  82. public void setHeader(String arg0,String arg1) throws MessagingException{
  83. mimeMessage.setHeader(arg0, arg1);
  84. }
  85. /** * 设置邮件接收人地址 <单人发送> * @param recipient * @throws MessagingException */
  86. public void setRecipient(String recipient) throws MessagingException{
  87. mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(recipient));
  88. }
  89. /** * 设置邮件接收人地址 <多人发送> * @param list * @throws MessagingException * @throws AddressException */
  90. public String setRecipients(List<String> recs) throws AddressException, MessagingException{
  91. if(recs.isEmpty()){
  92. return "接收人地址为空!";
  93. }
  94. for(String str:recs){
  95. mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(str));
  96. }
  97. return "加入接收人地址成功!";
  98. }
  99. /** * 设置邮件接收人地址 <多人发送> * @param StringBuffer<parms,parms2,parms.....> * @throws MessagingException * @throws AddressException */
  100. @SuppressWarnings("static-access")
  101. public String setRecipients(StringBuffer sb) throws AddressException, MessagingException{
  102. if(sb==null||"".equals(sb)){
  103. return "字符串数据为空!";
  104. }
  105. Address []address = new InternetAddress().parse(sb.toString());
  106. mimeMessage.addRecipients(Message.RecipientType.TO, address);
  107. return "收件人加入成功";
  108. }
  109. /** * 设置邮件发送人的名字 * @param from * @throws UnsupportedEncodingException * @throws MessagingException */
  110. public void setFrom(String from) throws UnsupportedEncodingException, MessagingException{
  111. mimeMessage.setFrom(new InternetAddress(username,from));
  112. }
  113. /** * 发送邮件<单人发送> * return 是否发送成功 * @throws MessagingException */
  114. public String sendMessage() throws MessagingException{
  115. Transport.send(mimeMessage);
  116. return "success";
  117. }
  118. /** * 设置附件 * @param file 发送文件的路径 */
  119. public void setMultipart(String file) throws MessagingException, IOException{
  120. if(multipart==null){
  121. multipart = new MimeMultipart();
  122. }
  123. multipart.addBodyPart(writeFiles(file));
  124. mimeMessage.setContent(multipart);
  125. }
  126. /** * 设置附件<添加多附件> * @param fileList<接收List集合> * @throws MessagingException * @throws IOException */
  127. public void setMultiparts(List<String> fileList) throws MessagingException, IOException{
  128. if(multipart==null){
  129. multipart = new MimeMultipart();
  130. }
  131. for(String s:fileList){
  132. multipart.addBodyPart(writeFiles(s));
  133. }
  134. mimeMessage.setContent(multipart);
  135. }
  136. /** * 发送文本内容,设置编码方式 * <方法与发送附件配套使用> * <发送普通的文本内容请使用setText()方法> * @param s * @param type * @throws MessagingException */
  137. public void setContent(String s,String type) throws MessagingException{
  138. if(multipart==null){
  139. multipart = new MimeMultipart();
  140. }
  141. bodypart = new MimeBodyPart();
  142. bodypart.setContent(s, type);
  143. multipart.addBodyPart(bodypart);
  144. mimeMessage.setContent(multipart);
  145. mimeMessage.saveChanges();
  146. }
  147. /** * 读取附件 * @param filePath * @return * @throws IOException * @throws MessagingException */
  148. public BodyPart writeFiles(String filePath)throws IOException, MessagingException{
  149. File file = new File(filePath);
  150. if(!file.exists()){
  151. throw new IOException("文件不存在!请确定文件路径是否正确");
  152. }
  153. bodypart = new MimeBodyPart();
  154. DataSource dataSource = new FileDataSource(file);
  155. bodypart.setDataHandler(new DataHandler(dataSource));
  156. //文件名要加入编码,不然出现乱码
  157. bodypart.setFileName(MimeUtility.encodeText(file.getName()));
  158. return bodypart;
  159. }
  160. }

2、测试类:

  1. package com.pleasurewithriding.assistantclass;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.Date;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import javax.mail.MessagingException;
  9. public class TestSend
  10. {
  11. public static void main(String[] args) throws MessagingException, IOException
  12. {
  13. Map<String,String> map= new HashMap<String,String>();
  14. ***SendMail mail = new SendMail("QQ号@qq.com","**你的授权码***");***
  15. map.put("mail.smtp.host", "smtp.qq.com");
  16. //暂时未成功,需要调试
  17. /*SendMail mail = new SendMail("14789****@sina.cn","***miya"); map.put("mail.smtp.host", "smtp.sina.com");*/
  18. map.put("mail.smtp.auth", "true");
  19. *****map.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
  20. map.put("mail.smtp.port", "465");
  21. map.put("mail.smtp.socketFactory.port", "465");*****
  22. mail.setPros(map);
  23. mail.initMessage();
  24. /* * 添加收件人有三种方法: * 1,单人添加(单人发送)调用setRecipient(str);发送String类型 * 2,多人添加(群发)调用setRecipients(list);发送list集合类型 * 3,多人添加(群发)调用setRecipients(sb);发送StringBuffer类型 */
  25. List<String> list = new ArrayList<String>();
  26. list.add("****@qq.com");
  27. //list.add("***92@sina.cn");
  28. list.add("****@163.com");
  29. mail.setRecipients(list);
  30. /*String defaultStr = "283942930@qq.com,429353942@qq.com,2355663819@qq.com,381766286@qq.com; StringBuffer sb = new StringBuffer(); sb.append(defaultStr); sb.append(",316121113@qq.com"); mail.setRecipients(sb);*/
  31. mail.setSubject("测试邮箱");
  32. //mail.setText("谢谢合作");
  33. mail.setDate(new Date());
  34. mail.setFrom("MY");
  35. // mail.setMultipart("D:你你你.txt");
  36. mail.setContent("谢谢合作", "text/html; charset=UTF-8");
  37. /*List<String> fileList = new ArrayList<String>(); fileList.add("D:1.jpg"); fileList.add("D:activation.zip"); fileList.add("D:dstz.sql"); fileList.add("D:软件配置要求.doc"); mail.setMultiparts(fileList);*/
  38. System.out.println(mail.sendMessage());
  39. }
  40. }

代码中斜体加粗的地方就是我的改动:
1、构造函数初始化邮箱地址和密码的地方,前辈用的是163邮箱,我没去测试163邮箱了,直接用QQ邮箱了,但是要注意 QQ邮箱的密码不是你的 邮箱独立密码,当然更不是QQ密码,而是邮箱授权码,我之前在网上搜了很多文章,由于时间较早,都是用的邮箱独立密码(那时候腾讯还没有搞出授权码这个东西)测试成功,这个造成了我一时的困扰。不知道163邮箱是不是也出了授权码的概念,如果是,那么估计也是要用授权码代替密码吧,有兴趣的可以自己去测试。关于QQ邮箱授权码的获取,
进入QQ邮箱=》设置=》账户,在开启几个服务三方服务的时候,会要求获取授权码:
这里写图片描述

2、现在的QQ邮箱要求 使用 SSL 连接,当我把前辈的代码直接运行的时候,抛出了异常,叫什么 “530 Error: A secure connection is requiered(such as ssl)”,然后在网上找了别人的代码,发现加了这几句(我还没有去细究,等项目做完再说),
map.put(“mail.smtp.socketFactory.class”, “javax.net.ssl.SSLSocketFactory”);
map.put(“mail.smtp.port”, “465”);
map.put(“mail.smtp.socketFactory.port”, “465”);
3、如果你想看到 javamail 运行的 过程,加上 session.setDebug(true),我的源码里面已经加上了。

我的源码文件就不上了,因为所有代码都贴上来了,直接 copy 就可以的,好了,就说这么多,希望对跟我一样的小白有点帮助

发表评论

表情:
评论列表 (有 0 条评论,374人围观)

还没有评论,来说两句吧...

相关阅读