转自:https://blog.csdn.net/star_fly4/article/details/52037587

一、RFC882文档简单说明

  RFC882文档规定了如何编写一封简单的邮件(纯文本邮件),一封简单的邮件包含邮件头和邮件体两个部分,邮件头和邮件体之间使用空行分隔。

  邮件头包含的内容有:

  1. from字段   --用于指明发件人
  2. to字段       --用于指明收件人
  3. subject字段  --用于说明邮件主题
  4. cc字段      -- 抄送,将邮件发送给收件人的同时抄送给另一个收件人,收件人可以看到邮件抄送给了谁
  5. bcc字段    -- 密送,将邮件发送给收件人的同时将邮件秘密发送给另一个收件人,收件人无法看到邮件密送给了

二、MIME协议简单介绍

  在我们的实际开发当中,一封邮件既可能包含图片,又可能包含有附件,在这样的情况下,RFC882文档规定的邮件格式就无法满足要求了。

  MIME协议是对RFC822文档的升级和补充,它描述了如何生产一封复杂的邮件。通常我们把MIME协议描述的邮件称之为MIME邮件。MIME协议描述的数据称之为MIME消息。
  对于一封复杂邮件,如果包含了多个不同的数据,MIME协议规定了要使用分隔线对多段数据进行分隔,并使用Content-Type头字段对数据的类型、以及多个数据之间的关系进行描述。

三、使用JavaMail创建邮件和发送邮件图解

  JavaMail创建的邮件是基于MIME协议的。因此可以使用JavaMail创建出包含图片,包含附件的复杂邮件。

四、邮件发送代码

 

1 导入开发包mail.jar  下载地址

  1. package cjr.javamail;
  2.  
  3. import java.io.File;
  4. import java.util.Date;
  5. import java.util.Properties;
  6.  
  7. import javax.activation.DataHandler;
  8. import javax.activation.DataSource;
  9. import javax.activation.FileDataSource;
  10. import javax.mail.Address;
  11. import javax.mail.Authenticator;
  12. import javax.mail.Message.RecipientType;
  13. import javax.mail.MessagingException;
  14. import javax.mail.PasswordAuthentication;
  15. import javax.mail.Session;
  16. import javax.mail.Transport;
  17. import javax.mail.internet.InternetAddress;
  18. import javax.mail.internet.MimeBodyPart;
  19. import javax.mail.internet.MimeMessage;
  20. import javax.mail.internet.MimeMultipart;
  21. import javax.mail.internet.MimeUtility;
  22.  
  23. import org.junit.Test;
  24.  
  25. public class SendEmail {
  26.  
  27. // 邮件发送协议
  28. private final static String PROTOCOL = "smtp";
  29.  
  30. // SMTP邮件服务器
  31. private final static String HOST = "smtp.163.com";
  32.  
  33. // SMTP邮件服务器默认端口
  34. private final static String PORT = "25";
  35.  
  36. // 是否要求身份认证
  37. private final static String IS_AUTH = "true";
  38.  
  39. // 是否启用调试模式(启用调试模式可打印客户端与服务器交互过程时一问一答的响应消息)
  40. private final static String IS_ENABLED_DEBUG_MOD = "true";
  41.  
  42. // 发件人
  43. private static String from = "chenxingxing745@163.com";
  44. private static String verification_code = "cx*******29";
  45.  
  46. // 收件人
  47. private static String to = "chenjiaren745@163.com";
  48.  
  49. // 初始化连接邮件服务器的会话信息
  50. private static Properties props = null;
  51.  
  52. static {
  53. props = new Properties();
  54. props.setProperty("mail.transport.protocol", PROTOCOL);
  55. props.setProperty("mail.smtp.host", HOST);
  56. props.setProperty("mail.smtp.port", PORT);
  57. props.setProperty("mail.smtp.auth", IS_AUTH);
  58. props.setProperty("mail.debug",IS_ENABLED_DEBUG_MOD);
  59. }
  60.  
  61. /**
  62. * 发送简单的文本邮件
  63. */
  64. @Test
  65. public void sendTextEmail() throws Exception {
  66. // 创建Session实例对象
  67. Session session = Session.getDefaultInstance(props);
  68.  
  69. // 创建MimeMessage实例对象
  70. MimeMessage message = new MimeMessage(session);
  71. // 设置发件人
  72. message.setFrom(new InternetAddress(from));
  73. // 设置邮件主题
  74. message.setSubject("使用javamail发送简单文本邮件");
  75. // 设置收件人
  76. message.setRecipient(RecipientType.TO, new InternetAddress(to));
  77. // 设置发送时间
  78. message.setSentDate(new Date());
  79. // 设置纯文本内容为邮件正文
  80. message.setText("使用POP3协议发送文本邮件测试!!!");
  81. // 保存并生成最终的邮件内容
  82. message.saveChanges();
  83.  
  84. // 获得Transport实例对象
  85. Transport transport = session.getTransport();
  86. // 打开连接
  87. transport.connect("chenxingxing745", "cx*******9");
  88. // 将message对象传递给transport对象,将邮件发送出去
  89. transport.sendMessage(message, message.getAllRecipients());
  90. // 关闭连接
  91. transport.close();
  92. }
  93.  
  94. /**
  95. * 发送简单的html邮件
  96. */
  97. @Test
  98. public void sendHtmlEmail() throws Exception {
  99. // 创建Session实例对象
  100. Session session = Session.getInstance(props, new MyAuthenticator(from,verification_code));
  101.  
  102. // 创建MimeMessage实例对象
  103. MimeMessage message = new MimeMessage(session);
  104. // 设置邮件主题
  105. message.setSubject("html邮件主题");
  106. // 设置发送人
  107. message.setFrom(new InternetAddress(from));
  108. // 设置发送时间
  109. message.setSentDate(new Date());
  110. // 设置收件人
  111. message.setRecipients(RecipientType.TO, InternetAddress.parse(to));
  112. // 设置html内容为邮件正文,指定MIME类型为text/html类型,并指定字符编码为gbk
  113. message.setContent("<span style='color:red;'>html邮件测试...</span>","text/html;charset=gbk");
  114.  
  115. // 保存并生成最终的邮件内容
  116. message.saveChanges();
  117.  
  118. // 发送邮件
  119. Transport.send(message);
  120. }
  121.  
  122. /**
  123. * 发送带内嵌图片的HTML邮件
  124. */
  125. @Test
  126. public void sendHtmlWithInnerImageEmail() throws MessagingException {
  127. // 创建Session实例对象
  128. Session session = Session.getDefaultInstance(props, new MyAuthenticator(from,verification_code));
  129.  
  130. // 创建邮件内容
  131. MimeMessage message = new MimeMessage(session);
  132. // 邮件主题,并指定编码格式
  133. message.setSubject("带内嵌图片的HTML邮件", "utf-8");
  134. // 发件人
  135. message.setFrom(new InternetAddress(from));
  136. // 收件人
  137. message.setRecipients(RecipientType.TO, InternetAddress.parse(to));
  138. message.setSentDate(new Date());
  139.  
  140. // 创建一个MIME子类型为“related”的MimeMultipart对象
  141. MimeMultipart mp = new MimeMultipart("related");
  142. // 创建一个表示正文的MimeBodyPart对象,并将它加入到前面创建的MimeMultipart对象中
  143. MimeBodyPart htmlPart = new MimeBodyPart();
  144. mp.addBodyPart(htmlPart);
  145. // 将MimeMultipart对象设置为整个邮件的内容
  146. message.setContent(mp);
  147.  
  148. // 创建一个表示图片资源的MimeBodyPart对象,将将它加入到前面创建的MimeMultipart对象中
  149. MimeBodyPart imagePart = new MimeBodyPart();
  150. MimeBodyPart imagePart1 = new MimeBodyPart();
  151. mp.addBodyPart(imagePart);
  152. mp.addBodyPart(imagePart1);
  153.  
  154. // 设置内嵌图片邮件体
  155. DataSource ds = new FileDataSource(new File("src/psb.jpg"));
  156. DataHandler dh = new DataHandler(ds);
  157. imagePart.setDataHandler(dh);
  158. imagePart.setContentID("psb.jpg"); // 设置内容编号,用于其它邮件体引用
  159.  
  160. DataSource ds1 = new FileDataSource(new File("src/loading.gif"));
  161. DataHandler dh1 = new DataHandler(ds1);
  162. imagePart1.setDataHandler(dh1);
  163. imagePart1.setContentID("loading.gif"); // 设置内容编号,用于其它邮件体引用
  164.  
  165. // 创建一个MIME子类型为"alternative"的MimeMultipart对象,并作为前面创建的htmlPart对象的邮件内容
  166. MimeMultipart htmlMultipart = new MimeMultipart("alternative");
  167. // 创建一个表示html正文的MimeBodyPart对象
  168. MimeBodyPart htmlBodypart = new MimeBodyPart();
  169. // 其中cid=androidlogo.gif是引用邮件内部的图片,即imagePart.setContentID("androidlogo.gif");方法所保存的图片
  170. htmlBodypart.setContent("<span style='color:red;'>这是带内嵌图片的HTML邮件哦!!!<img src=\"cid:psb.jpg\" /></span>多张图片<img src=\"cid:psb.jpg\" />侧认<img src=\"cid:loading.gif\" />识","text/html;charset=utf-8");
  171. htmlMultipart.addBodyPart(htmlBodypart);
  172. htmlPart.setContent(htmlMultipart);
  173.  
  174. // 保存并生成最终的邮件内容
  175. message.saveChanges();
  176.  
  177. // 发送邮件
  178. Transport.send(message);
  179. }
  180.  
  181. /**
  182. * 发送带内嵌图片、附件、多收件人(显示邮箱姓名)、邮件优先级、阅读回执的完整的HTML邮件
  183. */
  184. @Test
  185. public void sendMultipleEmail() throws Exception {
  186. String charset = "utf-8"; // 指定中文编码格式
  187. // 创建Session实例对象
  188. Session session = Session.getInstance(props,new MyAuthenticator(from,verification_code));
  189.  
  190. // 创建MimeMessage实例对象
  191. MimeMessage message = new MimeMessage(session);
  192. // 设置主题
  193. message.setSubject("使用JavaMail发送混合组合类型的邮件测试");
  194. // 设置发送人
  195. message.setFrom(new InternetAddress(from,"163测试邮箱",charset));
  196. // 设置收件人
  197. message.setRecipients(RecipientType.TO,
  198. new Address[] {
  199. // 参数1:邮箱地址,参数2:姓名(在客户端收件只显示姓名,而不显示邮件地址),参数3:姓名中文字符串编码
  200. new InternetAddress("517697206@qq.com", "张三_qq", charset),
  201. new InternetAddress("chenjiaren745@163.com", "李四_163", charset),
  202. }
  203. );
  204. // 设置抄送
  205. //message.setRecipient(RecipientType.CC, new InternetAddress("xyang0917@gmail.com","王五_gmail",charset));
  206. // 设置密送
  207. //message.setRecipient(RecipientType.BCC, new InternetAddress("xyang0917@qq.com", "赵六_QQ", charset));
  208. // 设置发送时间
  209. message.setSentDate(new Date());
  210. // 设置回复人(收件人回复此邮件时,默认收件人)
  211. message.setReplyTo(InternetAddress.parse("\"" + MimeUtility.encodeText("田七") + "\" <chenxingxing745@163.com>"));
  212. // 设置优先级(1:紧急 3:普通 5:低)
  213. message.setHeader("X-Priority", "1");
  214. // 要求阅读回执(收件人阅读邮件时会提示回复发件人,表明邮件已收到,并已阅读)
  215. message.setHeader("Disposition-Notification-To", from);
  216.  
  217. // 创建一个MIME子类型为"mixed"的MimeMultipart对象,表示这是一封混合组合类型的邮件
  218. MimeMultipart mailContent = new MimeMultipart("mixed");
  219. message.setContent(mailContent);
  220.  
  221. // 附件
  222. MimeBodyPart attach1 = new MimeBodyPart();
  223. MimeBodyPart attach2 = new MimeBodyPart();
  224. // 内容
  225. MimeBodyPart mailBody = new MimeBodyPart();
  226.  
  227. // 将附件和内容添加到邮件当中
  228. mailContent.addBodyPart(attach1);
  229. mailContent.addBodyPart(attach2);
  230. mailContent.addBodyPart(mailBody);
  231.  
  232. // 附件1(利用jaf框架读取数据源生成邮件体)
  233. DataSource ds1 = new FileDataSource("src/loading.gif");
  234. DataHandler dh1 = new DataHandler(ds1);
  235. attach1.setFileName(MimeUtility.encodeText("loading.gif"));
  236. attach1.setDataHandler(dh1);
  237.  
  238. // 附件2
  239. DataSource ds2 = new FileDataSource("src/车.png");
  240. DataHandler dh2 = new DataHandler(ds2);
  241. System.out.println("======================"+dh2.getName()+"====================");
  242. attach2.setDataHandler(dh2);
  243. attach2.setFileName(MimeUtility.encodeText(dh2.getName()));
  244.  
  245. // 邮件正文(内嵌图片+html文本)
  246. MimeMultipart body = new MimeMultipart("related"); //邮件正文也是一个组合体,需要指明组合关系
  247. mailBody.setContent(body);
  248.  
  249. // 邮件正文由html和图片构成
  250. MimeBodyPart imgPart = new MimeBodyPart();
  251. MimeBodyPart htmlPart = new MimeBodyPart();
  252. body.addBodyPart(imgPart);
  253. body.addBodyPart(htmlPart);
  254.  
  255. // 正文图片
  256. DataSource ds3 = new FileDataSource("src/psb.jpg");
  257. DataHandler dh3 = new DataHandler(ds3);
  258. imgPart.setDataHandler(dh3);
  259. imgPart.setContentID("psb.jpg");
  260.  
  261. // html邮件内容
  262. MimeMultipart htmlMultipart = new MimeMultipart("alternative");
  263. htmlPart.setContent(htmlMultipart);
  264. MimeBodyPart htmlContent = new MimeBodyPart();
  265. htmlContent.setContent(
  266. "<span style='color:red'>这是我自己用java mail发送的邮件哦!" +
  267. "<img src='cid:psb.jpg' /></span> 复杂邮件"
  268. , "text/html;charset=gbk");
  269. htmlMultipart.addBodyPart(htmlContent);
  270.  
  271. // 保存邮件内容修改
  272. message.saveChanges();
  273.  
  274. // 发送邮件
  275. Transport.send(message);
  276. }
  277.  
  278. }
  279.  
  280. /**
  281. * 向邮件服务器提交认证信息
  282. */
  283. class MyAuthenticator extends Authenticator {
  284.  
  285. private String username = "chenxingxing745";
  286.  
  287. private String password = "<span style="line-height: 20.8px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">cx*******29</span>";
  288.  
  289. public MyAuthenticator() {
  290. super();
  291. }
  292.  
  293. public MyAuthenticator(String username, String password) {
  294. super();
  295. this.username = username;
  296. this.password = password;
  297. }
  298.  
  299. @Override
  300. protected PasswordAuthentication getPasswordAuthentication() {
  301.  
  302. return new PasswordAuthentication(username, password);
  303. }
  304. }

五、邮件接收解析

  1. package cjr.javamail;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.BufferedOutputStream;
  5. import java.io.File;
  6. import java.io.FileNotFoundException;
  7. import java.io.FileOutputStream;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.io.UnsupportedEncodingException;
  11. import java.text.SimpleDateFormat;
  12. import java.util.Date;
  13. import java.util.Properties;
  14.  
  15. import javax.mail.Address;
  16. import javax.mail.BodyPart;
  17. import javax.mail.Flags;
  18. import javax.mail.Folder;
  19. import javax.mail.Message;
  20. import javax.mail.MessagingException;
  21. import javax.mail.Multipart;
  22. import javax.mail.Part;
  23. import javax.mail.Session;
  24. import javax.mail.Store;
  25. import javax.mail.internet.InternetAddress;
  26. import javax.mail.internet.MimeMessage;
  27. import javax.mail.internet.MimeMultipart;
  28. import javax.mail.internet.MimeUtility;
  29.  
  30. import org.junit.Test;
  31.  
  32. public class ReceiveMail {
  33. private static final String PROTOCOL = "pop3";
  34. private static final String USERNAME = "chenjiaren745@163.com";
  35. private static final String LOGINPASS = "<span style="line-height: 20.8px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">cx*******29</span><span style="line-height: 20.8px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;">"; </span>
  36. private static final String DIR = "D:\\mailTemp\\";
  37.  
  38. // 初始化连接邮件服务器的会话信息
  39. private static Properties props = null;
  40. static{
  41. props = new Properties();
  42. props.setProperty("mail.store.protocol", "pop3"); // 协议
  43. props.setProperty("mail.pop3.port", "110"); // 端口
  44. props.setProperty("mail.pop3.host", "pop3.163.com"); // pop3服务器
  45. File dir = new File(DIR);
  46. System.out.println(!dir.exists());
  47. if(!dir.exists())
  48. dir.mkdirs();
  49. System.out.println(dir.isDirectory());
  50. }
  51.  
  52. @Test
  53. public void receive() throws Exception {
  54.  
  55. // 创建Session实例对象
  56. Session session = Session.getInstance(props);
  57. Store store = session.getStore(PROTOCOL);
  58. store.connect(USERNAME, LOGINPASS);
  59.  
  60. // 获得收件箱
  61. Folder folder = store.getFolder("INBOX");
  62. /* Folder.READ_ONLY:只读权限
  63. * Folder.READ_WRITE:可读可写(可以修改邮件的状态)
  64. */
  65. folder.open(Folder.READ_WRITE); //打开收件箱
  66.  
  67. // 由于POP3协议无法获知邮件的状态,所以getUnreadMessageCount得到的是收件箱的邮件总数
  68. System.out.println("未读邮件数: " + folder.getUnreadMessageCount());
  69.  
  70. // 由于POP3协议无法获知邮件的状态,所以下面得到的结果始终都是为0
  71. System.out.println("删除邮件数: " + folder.getDeletedMessageCount());
  72. System.out.println("新邮件: " + folder.getNewMessageCount());
  73.  
  74. // 获得收件箱中的邮件总数
  75. System.out.println("邮件总数: " + folder.getMessageCount());
  76.  
  77. // 得到收件箱中的所有邮件,并解析
  78. Message[] messages = folder.getMessages();
  79. parseMessage(messages);
  80.  
  81. //释放资源
  82. folder.close(true);
  83. store.close();
  84. }
  85.  
  86. /**
  87. * 解析邮件
  88. * @param messages 要解析的邮件列表
  89. */
  90. public void parseMessage(Message ...messages) throws MessagingException, IOException {
  91. if (messages == null || messages.length < 1)
  92. throw new MessagingException("未找到要解析的邮件!");
  93.  
  94. // 解析所有邮件
  95. for (int i = 0, count = messages.length; i < count; i++) {
  96. MimeMessage msg = (MimeMessage) messages[i];
  97. System.out.println("------------------解析第" + msg.getMessageNumber() + "封邮件-------------------- ");
  98. System.out.println("主题: " + getSubject(msg));
  99. System.out.println("发件人: " + getFrom(msg));
  100. System.out.println("收件人:" + getReceiveAddress(msg, null));
  101. System.out.println("发送时间:" + getSentDate(msg, null));
  102. System.out.println("是否已读:" + isSeen(msg));
  103. System.out.println("邮件优先级:" + getPriority(msg));
  104. System.out.println("是否需要回执:" + isReplySign(msg));
  105. System.out.println("邮件大小:" + msg.getSize() * 1024 + "kb");
  106. boolean isContainerAttachment = isContainAttachment(msg);
  107. System.out.println("是否包含附件:" + isContainerAttachment);
  108. if (isContainerAttachment) {
  109. saveAttachment(msg, DIR + msg.getSubject() + "_"); //保存附件
  110. }
  111. StringBuffer content = new StringBuffer(30);
  112. getMailTextContent(msg, content);
  113. System.out.println("邮件正文:" + (content.length() > 100 ? content.substring(0,100) + "..." : content));
  114. System.out.println("------------------第" + msg.getMessageNumber() + "封邮件解析结束-------------------- ");
  115. System.out.println();
  116. }
  117. }
  118.  
  119. /**
  120. * 获得邮件主题
  121. * @param msg 邮件内容
  122. * @return 解码后的邮件主题
  123. */
  124. public static String getSubject(MimeMessage msg) throws UnsupportedEncodingException, MessagingException {
  125. return MimeUtility.decodeText(msg.getSubject());
  126. }
  127.  
  128. /**
  129. * 获得邮件发件人
  130. * @param msg 邮件内容
  131. * @return 姓名 <Email地址>
  132. * @throws MessagingException
  133. * @throws UnsupportedEncodingException
  134. */
  135. public static String getFrom(MimeMessage msg) throws MessagingException, UnsupportedEncodingException {
  136. String from = "";
  137. Address[] froms = msg.getFrom();
  138. if (froms.length < 1)
  139. throw new MessagingException("没有发件人!");
  140.  
  141. InternetAddress address = (InternetAddress) froms[0];
  142. String person = address.getPersonal();
  143. if (person != null) {
  144. person = MimeUtility.decodeText(person) + " ";
  145. } else {
  146. person = "";
  147. }
  148. from = person + "<" + address.getAddress() + ">";
  149.  
  150. return from;
  151. }
  152.  
  153. /**
  154. * 根据收件人类型,获取邮件收件人、抄送和密送地址。如果收件人类型为空,则获得所有的收件人
  155. * <p>Message.RecipientType.TO 收件人</p>
  156. * <p>Message.RecipientType.CC 抄送</p>
  157. * <p>Message.RecipientType.BCC 密送</p>
  158. * @param msg 邮件内容
  159. * @param type 收件人类型
  160. * @return 收件人1 <邮件地址1>, 收件人2 <邮件地址2>, ...
  161. * @throws MessagingException
  162. */
  163. public static String getReceiveAddress(MimeMessage msg, Message.RecipientType type) throws MessagingException {
  164. StringBuffer receiveAddress = new StringBuffer();
  165. Address[] addresss = null;
  166. if (type == null) {
  167. addresss = msg.getAllRecipients();
  168. } else {
  169. addresss = msg.getRecipients(type);
  170. }
  171.  
  172. if (addresss == null || addresss.length < 1)
  173. throw new MessagingException("没有收件人!");
  174. for (Address address : addresss) {
  175. InternetAddress internetAddress = (InternetAddress)address;
  176. receiveAddress.append(internetAddress.toUnicodeString()).append(",");
  177. }
  178.  
  179. receiveAddress.deleteCharAt(receiveAddress.length()-1); //删除最后一个逗号
  180.  
  181. return receiveAddress.toString();
  182. }
  183.  
  184. /**
  185. * 获得邮件发送时间
  186. * @param msg 邮件内容
  187. * @return yyyy年mm月dd日 星期X HH:mm
  188. * @throws MessagingException
  189. */
  190. public static String getSentDate(MimeMessage msg, String pattern) throws MessagingException {
  191. Date receivedDate = msg.getSentDate();
  192. if (receivedDate == null)
  193. return "";
  194.  
  195. if (pattern == null || "".equals(pattern))
  196. pattern = "yyyy年MM月dd日 E HH:mm ";
  197.  
  198. return new SimpleDateFormat(pattern).format(receivedDate);
  199. }
  200.  
  201. /**
  202. * 判断邮件中是否包含附件
  203. * @param msg 邮件内容
  204. * @return 邮件中存在附件返回true,不存在返回false
  205. * @throws MessagingException
  206. * @throws IOException
  207. */
  208. public static boolean isContainAttachment(Part part) throws MessagingException, IOException {
  209. boolean flag = false;
  210. if (part.isMimeType("multipart/*")) {
  211. MimeMultipart multipart = (MimeMultipart) part.getContent();
  212. int partCount = multipart.getCount();
  213. for (int i = 0; i < partCount; i++) {
  214. BodyPart bodyPart = multipart.getBodyPart(i);
  215. String disp = bodyPart.getDisposition();
  216. if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {
  217. flag = true;
  218. } else if (bodyPart.isMimeType("multipart/*")) {
  219. flag = isContainAttachment(bodyPart);
  220. } else {
  221. String contentType = bodyPart.getContentType();
  222. if (contentType.indexOf("application") != -1) {
  223. flag = true;
  224. }
  225.  
  226. if (contentType.indexOf("name") != -1) {
  227. flag = true;
  228. }
  229. }
  230.  
  231. if (flag) break;
  232. }
  233. } else if (part.isMimeType("message/rfc822")) {
  234. flag = isContainAttachment((Part)part.getContent());
  235. }
  236. return flag;
  237. }
  238.  
  239. /**
  240. * 判断邮件是否已读
  241. * @param msg 邮件内容
  242. * @return 如果邮件已读返回true,否则返回false
  243. * @throws MessagingException
  244. */
  245. public static boolean isSeen(MimeMessage msg) throws MessagingException {
  246. return msg.getFlags().contains(Flags.Flag.SEEN);
  247. }
  248.  
  249. /**
  250. * 判断邮件是否需要阅读回执
  251. * @param msg 邮件内容
  252. * @return 需要回执返回true,否则返回false
  253. * @throws MessagingException
  254. */
  255. public static boolean isReplySign(MimeMessage msg) throws MessagingException {
  256. boolean replySign = false;
  257. String[] headers = msg.getHeader("Disposition-Notification-To");
  258. if (headers != null)
  259. replySign = true;
  260. return replySign;
  261. }
  262.  
  263. /**
  264. * 获得邮件的优先级
  265. * @param msg 邮件内容
  266. * @return 1(High):紧急 3:普通(Normal) 5:低(Low)
  267. * @throws MessagingException
  268. */
  269. public String getPriority(MimeMessage msg) throws MessagingException {
  270. String priority = "普通";
  271. String[] headers = msg.getHeader("X-Priority");
  272. if (headers != null) {
  273. String headerPriority = headers[0];
  274. if (headerPriority.indexOf("1") != -1 || headerPriority.indexOf("High") != -1)
  275. priority = "紧急";
  276. else if (headerPriority.indexOf("5") != -1 || headerPriority.indexOf("Low") != -1)
  277. priority = "低";
  278. else
  279. priority = "普通";
  280. }
  281. return priority;
  282. }
  283.  
  284. /**
  285. * 获得邮件文本内容
  286. * @param part 邮件体
  287. * @param content 存储邮件文本内容的字符串
  288. * @throws MessagingException
  289. * @throws IOException
  290. */
  291. public void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {
  292. //如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
  293. boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
  294. if (part.isMimeType("text/*") && !isContainTextAttach) {
  295. content.append(part.getContent().toString());
  296. } else if (part.isMimeType("message/rfc822")) {
  297. getMailTextContent((Part)part.getContent(),content);
  298. } else if (part.isMimeType("multipart/*")) {
  299. Multipart multipart = (Multipart) part.getContent();
  300. int partCount = multipart.getCount();
  301. for (int i = 0; i < partCount; i++) {
  302. BodyPart bodyPart = multipart.getBodyPart(i);
  303. getMailTextContent(bodyPart,content);
  304. }
  305. }
  306. }
  307.  
  308. /**
  309. * 保存附件
  310. * @param part 邮件中多个组合体中的其中一个组合体
  311. * @param destDir 附件保存目录
  312. * @throws UnsupportedEncodingException
  313. * @throws MessagingException
  314. * @throws FileNotFoundException
  315. * @throws IOException
  316. */
  317. public void saveAttachment(Part part, String destDir) throws UnsupportedEncodingException, MessagingException,
  318. FileNotFoundException, IOException {
  319. if (part.isMimeType("multipart/*")) {
  320. Multipart multipart = (Multipart) part.getContent(); //复杂体邮件
  321. //复杂体邮件包含多个邮件体
  322. int partCount = multipart.getCount();
  323. for (int i = 0; i < partCount; i++) {
  324. //获得复杂体邮件中其中一个邮件体
  325. BodyPart bodyPart = multipart.getBodyPart(i);
  326. //某一个邮件体也有可能是由多个邮件体组成的复杂体
  327. String disp = bodyPart.getDisposition();
  328. if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {
  329. InputStream is = bodyPart.getInputStream();
  330. saveFile(is, destDir, decodeText(bodyPart.getFileName()));
  331. } else if (bodyPart.isMimeType("multipart/*")) {
  332. saveAttachment(bodyPart,destDir);
  333. } else {
  334. String contentType = bodyPart.getContentType();
  335. if (contentType.indexOf("name") != -1 || contentType.indexOf("application") != -1) {
  336. saveFile(bodyPart.getInputStream(), destDir, decodeText(bodyPart.getFileName()));
  337. }
  338. }
  339. }
  340. } else if (part.isMimeType("message/rfc822")) {
  341. saveAttachment((Part) part.getContent(),destDir);
  342. }
  343. }
  344.  
  345. /**
  346. * 读取输入流中的数据保存至指定目录
  347. * @param is 输入流
  348. * @param fileName 文件名
  349. * @param destDir 文件存储目录
  350. * @throws FileNotFoundException
  351. * @throws IOException
  352. */
  353. private void saveFile(InputStream is, String destDir, String fileName)
  354. throws FileNotFoundException, IOException {
  355. BufferedInputStream bis = new BufferedInputStream(is);
  356. BufferedOutputStream bos = new BufferedOutputStream(
  357. new FileOutputStream(new File(destDir + fileName)));
  358. int len = -1;
  359. while ((len = bis.read()) != -1) {
  360. bos.write(len);
  361. bos.flush();
  362. }
  363. bos.close();
  364. bis.close();
  365. }
  366.  
  367. /**
  368. * 文本解码
  369. * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本
  370. * @return 解码后的文本
  371. * @throws UnsupportedEncodingException
  372. */
  373. public String decodeText(String encodeText) throws UnsupportedEncodingException {
  374. if (encodeText == null || "".equals(encodeText)) {
  375. return "";
  376. } else {
  377. return MimeUtility.decodeText(encodeText);
  378. }
  379. }
  380. }
注意:
1  getUnreadMessageCount 获取未读邮件数量,getNewMessageCount 获取新邮件数量   获取值和实际值不一致。 目前测试时未读邮件数量等于总邮件数量,新邮件数量等于0 ,实际是有已读邮件,未读邮件, 产生原因待查。

javaMail 邮件发送和接收示例,支持正文图片、html、附件(转)的更多相关文章

  1. Android Java使用JavaMail API发送和接收邮件的代码示例

    JavaMail是Oracle甲骨文开发的Java邮件类API,支持多种邮件协议,这里我们就来看一下Java使用JavaMail API发送和接收邮件的代码示例 使用Javamail发送邮件,必需的j ...

  2. Java邮件发送与接收原理

    一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器.例如现在Internet很多提供邮件服务的厂商:sina.sohu ...

  3. SMTP协议及POP3协议-邮件发送和接收原理(转)

    本文转自https://blog.csdn.net/qq_15646957/article/details/52544099 感谢作者 一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 ...

  4. 应用层之E-mail服务及javaMail邮件发送的知识总结

    关于Email服务你需要知道的知识点: 概述: 今天来介绍一下应用层的电子邮件服务,我们每天几乎都在用,电子邮件(email)服务也是一种基于C/S模式的服务,它采用的是一种"存储-转发&q ...

  5. springboot邮件发送与接收读取

    发送邮件 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...

  6. Spring的javaMail邮件发送(带附件)

    项目中经常用到邮件功能,在这里简单的做一下笔记,方便日后温习. 首先需要在配置文件jdbc.properties添加: #------------ Mail ------------ mail.smt ...

  7. JavaMail邮件发送不成功的那些坑人情况及分析说明

    [我的Segmentfault原文]https://segmentfault.com/a/1190000008030346 前言   JavaMail的使用本身并不难,网上有不少案例,简单易懂,而且有 ...

  8. javamail邮件发送例子

    public class EmailTask{        // Session used by the javamail classes    private Session session;   ...

  9. JavaMail 邮件发送

    jar包部署 /** * 通过SMTP进行邮件集成 */ public class CmpSendMail { // 邮件发送服务器主机 private final static String HOS ...

随机推荐

  1. 配置国内的maven仓库

    MAVEN中央仓库 国内 配置Maven中央仓库路径的方法如下: 在Maven文件的conf目录中打开settings.xml文件 在文件中的servers节点和mirror节点中加入如下内容 华为云 ...

  2. FunDA(13)- 示范:用户自定义操作函数 - user defined tasks

    FunDA是一种函数式的编程工具,它所产生的程序是由许多功能单一的细小函数组合而成,这些函数就是用户自定义操作函数了.我们在前面曾经提过FunDA的运作原理模拟了数据流管道.流元素在管道流动的过程中被 ...

  3. Xshell多版本被曝存在后门,了解紧急响应修复预案

    近日,Xshell远程终端工具被爆出多个版本存在后门,无疑是安全圈的一个大新闻.恶意攻击者利用该后门可以收集到用户名密码等主机敏感信息,并将之传回攻击者的机器,导致服务器信息泄露,进一步可致使整个服务 ...

  4. StormUI详解

    StormUI由Cluster Summary,topology summary,supervisor summary,Nimbus Configuration四部分组成,如下图所示: Cluster ...

  5. n层满k叉树总共有多少个节点

    2叉树 1 3 7 对应公式为(2^n-1)/1 3叉树 1 4 13 对应公式为(3^n-1)/2 4叉树 1 5 21对应公式为(4^n-1)/3 ... n层k叉树,总共有(k^n-1)/k-1 ...

  6. Java并发编程实践读书笔记(5) 线程池的使用

    Executor与Task的耦合性 1,除非线程池很非常大,否则一个Task不要依赖同一个线程服务中的另外一个Task,因为这样容易造成死锁: 2,线程的执行是并行的,所以在设计Task的时候要考虑到 ...

  7. jQuery过滤选择器:first和:first-child的区别,CSS伪类:first-child

    最近项目中遇到需求:只在第一列不能删除,不显示小叉号:点击可添加一列,后面的列右上角显示小叉号,可以点击删除. 我是使用以下方法解决这个小需求 :CSS伪类选择器:first-child设置所有小叉号 ...

  8. 剑指offer四十七之求1+2+3+...+n

    一.题目 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 二.思路 1.需利用逻辑与的短路特性实现递归终 ...

  9. (转)AWK函数

    http://wiki.jikexueyuan.com/project/awk/built-in-functions.html-------内置函数 http://wiki.jikexueyuan.c ...

  10. 从一个例子学习 instanceof 和 getclass 的区别

    判断两个对象是否为同一类型,时常用到getclass 和 instanceof ,而这两个函数又是时常让人混淆.下面从一个例子说明两者的区别: public class Test_drive { pu ...