1、看效果
1.1、阿里云邮箱
1.2、163邮箱
2、代码
1 import com.sun.mail.imap.IMAPFolder; 2 import com.sun.mail.imap.protocol.IMAPProtocol; 3 import org.apache.tomcat.util.http.fileupload.IOUtils; 4 import org.springframework.util.ObjectUtils; 5 6 import javax.mail.*; 7 import javax.mail.internet.InternetAddress; 8 import javax.mail.internet.MimeMessage; 9 import javax.mail.internet.MimeUtility; 10 import java.io.*; 11 import java.text.ParseException; 12 import java.text.SimpleDateFormat; 13 import java.util.*; 14 15 public class ShowMail { 16 17 public static String NORM_DATETIME_PATTERN = "yyyy-MM-dd hh:mm:ss"; 18 private MimeMessage mimeMessage; 19 /** 20 * 附件下载后的存放目录 21 */ 22 private String saveAttachPath = ""; 23 /** 24 * 存放邮件内容的StringBuffer对象 25 */ 26 private StringBuffer bodyText = new StringBuffer(); 27 28 /** 29 * 构造函数,初始化一个MimeMessage对象 30 * 31 * @param mimeMessage 32 */ 33 public ShowMail(MimeMessage mimeMessage) { 34 this.mimeMessage = mimeMessage; 35 } 36 37 /** 38 * 获得发件人的地址和姓名 39 * 40 * @return 41 * @throws MessagingException 42 */ 43 public String getFrom() throws MessagingException { 44 InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom(); 45 String from = address[0].getAddress(); 46 if (from == null) { 47 from = ""; 48 } 49 String personal = address[0].getPersonal(); 50 51 if (personal == null) { 52 personal = ""; 53 } 54 55 String fromAddr = null; 56 if (personal != null || from != null) { 57 fromAddr = personal + "<" + from + ">"; 58 } 59 return fromAddr; 60 } 61 62 /** 63 * 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同 64 * 65 * @param type "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址 66 * @return 67 * @throws MessagingException 68 * @throws UnsupportedEncodingException 69 */ 70 public String getMailAddress(String type) throws MessagingException, UnsupportedEncodingException { 71 if (ObjectUtils.isEmpty(type)) { 72 return ""; 73 } 74 75 String addType = type.toUpperCase(); 76 77 if (!addType.equals("TO") && !addType.equals("CC") && !addType.equals("BCC")) { 78 return ""; 79 } 80 InternetAddress[] address; 81 82 if (addType.equals("TO")) { 83 address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.TO); 84 } else if (addType.equals("CC")) { 85 address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.CC); 86 } else { 87 address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.BCC); 88 } 89 90 if (ObjectUtils.isEmpty(address)) { 91 return ""; 92 } 93 StringBuilder mailAddr = new StringBuilder(); 94 String emailAddr; 95 String personal; 96 for (int i = 0; i < address.length; i++) { 97 emailAddr = address[i].getAddress(); 98 if (emailAddr == null) { 99 emailAddr = ""; 100 } else { 101 emailAddr = MimeUtility.decodeText(emailAddr); 102 } 103 personal = address[i].getPersonal(); 104 if (personal == null) { 105 personal = ""; 106 } else { 107 personal = MimeUtility.decodeText(personal); 108 } 109 mailAddr.append(",").append(personal).append("<").append(emailAddr).append(">"); 110 } 111 return mailAddr.toString().substring(1); 112 } 113 114 /** 115 * 获得邮件主题 116 * 117 * @return 118 * @throws MessagingException 119 * @throws UnsupportedEncodingException 120 */ 121 public String getSubject() throws MessagingException, UnsupportedEncodingException { 122 String subject = MimeUtility.decodeText(mimeMessage.getSubject()); 123 if (subject == null) { 124 subject = ""; 125 } 126 return subject; 127 } 128 129 /** 130 * 获得邮件发送日期 131 * 132 * @return 133 * @throws MessagingException 134 */ 135 public String getSentDate() throws MessagingException { 136 Date sentDate = mimeMessage.getSentDate(); 137 SimpleDateFormat format = new SimpleDateFormat(NORM_DATETIME_PATTERN); 138 return format.format(sentDate); 139 } 140 141 /** 142 * 获得邮件正文内容 143 * 144 * @return 145 */ 146 public String getBodyText() { 147 return bodyText.toString(); 148 } 149 150 /** 151 * 解析邮件,把得到的邮件内容保存到一个StringBuffer对象中,解析邮件 152 * 主要是根据MimeType类型的不同执行不同的操作,一步一步的解析 153 * @param part 154 * @throws MessagingException 155 * @throws IOException 156 */ 157 public void getMailContent(Part part) throws MessagingException, IOException { 158 159 String contentType = part.getContentType(); 160 161 int nameIndex = contentType.indexOf("name"); 162 163 boolean conName = false; 164 165 if (nameIndex != -1) { 166 conName = true; 167 } 168 169 if (part.isMimeType("text/plain") && conName == false) { 170 bodyText.append((String) part.getContent()); 171 } else if (part.isMimeType("text/html") && conName == false) { 172 bodyText.append((String) part.getContent()); 173 } else if (part.isMimeType("multipart/*")) { 174 Multipart multipart = (Multipart) part.getContent(); 175 int counts = multipart.getCount(); 176 for (int i = 0; i < counts; i++) { 177 this.getMailContent(multipart.getBodyPart(i)); 178 } 179 } else if (part.isMimeType("message/rfc822")) { 180 this.getMailContent((Part) part.getContent()); 181 } 182 } 183 184 /** 185 * 判断此邮件是否需要回执,如果需要回执返回"true",否则返回"false" 186 * 187 * @return 188 * @throws MessagingException 189 */ 190 public boolean getReplySign() throws MessagingException { 191 192 boolean replySign = false; 193 194 String needReply[] = mimeMessage.getHeader("Disposition-Notification-To"); 195 196 if (needReply != null) { 197 replySign = true; 198 } 199 return replySign; 200 } 201 202 /** 203 * 判断此邮件是否已读,如果未读返回false,反之返回true 204 * 205 * @return 206 * @throws MessagingException 207 */ 208 public boolean isNew() throws MessagingException { 209 boolean isNew = false; 210 Flags flags = mimeMessage.getFlags(); 211 Flags.Flag[] flag = flags.getSystemFlags(); 212 for (int i = 0; i < flag.length; i++) { 213 if (flag[i] == Flags.Flag.SEEN) { 214 isNew = true; 215 } 216 } 217 return isNew; 218 } 219 220 /** 221 * 判断此邮件是否包含附件 222 * 223 * @param part 224 * @return 225 * @throws MessagingException 226 * @throws IOException 227 */ 228 public boolean isContainAttach(Part part) throws MessagingException, IOException { 229 boolean attachFlag = false; 230 if (part.isMimeType("multipart/*")) { 231 Multipart mp = (Multipart) part.getContent(); 232 BodyPart mPart; 233 String conType; 234 for (int i = 0; i < mp.getCount(); i++) { 235 mPart = mp.getBodyPart(i); 236 String disposition = mPart.getDisposition(); 237 if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) { 238 attachFlag = true; 239 } else if (mPart.isMimeType("multipart/*")) { 240 attachFlag = this.isContainAttach(mPart); 241 } else { 242 conType = mPart.getContentType(); 243 if (conType.toLowerCase().indexOf("application") != -1 || conType.toLowerCase().indexOf("name") != -1){ 244 attachFlag = true; 245 } 246 } 247 } 248 } else if (part.isMimeType("message/rfc822")) { 249 attachFlag = isContainAttach((Part) part.getContent()); 250 } 251 return attachFlag; 252 } 253 254 /** 255 * 保存附件 256 * 257 * @param part 258 * @throws MessagingException 259 * @throws IOException 260 */ 261 public void saveAttachMent(Part part) throws MessagingException, IOException { 262 String fileName; 263 if (part.isMimeType("multipart/*")) { 264 Multipart mp = (Multipart) part.getContent(); 265 BodyPart mPart; 266 for (int i = 0; i < mp.getCount(); i++) { 267 mPart = mp.getBodyPart(i); 268 String disposition = mPart.getDisposition(); 269 if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) { 270 fileName = mPart.getFileName(); 271 if (null != fileName && fileName.toLowerCase().indexOf("gb2312") != -1) { 272 fileName = MimeUtility.decodeText(fileName); 273 } 274 this.saveFile(fileName, mPart.getInputStream()); 275 } else if (mPart.isMimeType("multipart/*")) { 276 this.saveAttachMent(mPart); 277 } else { 278 fileName = mPart.getFileName(); 279 if ((fileName != null) && (fileName.toLowerCase().indexOf("GB2312") != -1)) { 280 fileName = MimeUtility.decodeText(fileName); 281 this.saveFile(fileName, mPart.getInputStream()); 282 } 283 } 284 } 285 } else if (part.isMimeType("message/rfc822")) { 286 this.saveAttachMent((Part) part.getContent()); 287 } 288 } 289 290 /** 291 * 设置附件存放路径 292 * 293 * @param attachPath 294 */ 295 public void setAttachPath(String attachPath) { 296 this.saveAttachPath = attachPath; 297 } 298 299 /** 300 * 获得附件存放路径 301 * 302 * @return 303 */ 304 public String getAttachPath() { 305 return saveAttachPath; 306 } 307 308 /** 309 * 真正的保存附件到指定目录里 310 * 311 * @param fileName 312 * @param in 313 * @throws IOException 314 */ 315 private void saveFile(String fileName, InputStream in) throws IOException { 316 String osName = System.getProperty("os.name"); 317 String storeDir = this.getAttachPath(); 318 if (null == osName) { 319 osName = ""; 320 } 321 if (osName.toLowerCase().indexOf("win") != -1) { 322 if (ObjectUtils.isEmpty(storeDir)) 323 storeDir = "C:\tmp"; 324 } else { 325 storeDir = "/tmp"; 326 } 327 FileOutputStream fos = new FileOutputStream(new File(storeDir + File.separator + fileName)); 328 IOUtils.copy(in, fos); 329 IOUtils.closeQuietly(fos); 330 IOUtils.closeQuietly(in); 331 } 332 333 /** 334 * 获取阿里云邮箱信息 335 * 336 * @param host 邮件服务器 337 * @param username 邮箱名 338 * @param password 密码 339 * @param protocol 协议 340 * @return 341 * @throws MessagingException 342 */ 343 public static Message[] getALiYunMessage(String host, String username, String password, String protocol) throws MessagingException { 344 Properties props = new Properties(); 345 Session session = Session.getDefaultInstance(props, null); 346 347 Store store = session.getStore(protocol); 348 store.connect(host, username, password); 349 350 Folder folder = store.getFolder("INBOX"); 351 folder.open(Folder.READ_ONLY); 352 return folder.getMessages(); 353 } 354 355 356 /** 357 * 获取163邮箱信息 358 * 359 * @param host 360 * @param username 361 * @param password 362 * @param protocol 363 * @return 364 * @throws MessagingException 365 */ 366 public static Message[] getWEMessage(String host, String username, String password, String protocol) throws MessagingException { 367 Properties props = System.getProperties(); 368 props.setProperty("mail.store.protocol", protocol); 369 Session session = Session.getDefaultInstance(props, null); 370 Store store = session.getStore(protocol); 371 store.connect(host, username, password); 372 Folder folder = store.getFolder("INBOX"); 373 374 if (folder instanceof IMAPFolder) { 375 IMAPFolder imapFolder = (IMAPFolder)folder; 376 //javamail中使用id命令有校验checkOpened, 所以要去掉id方法中的checkOpened(); 377 imapFolder.doCommand(new IMAPFolder.ProtocolCommand() { 378 public Object doCommand(IMAPProtocol p) throws com.sun.mail.iap.ProtocolException { 379 p.id("FUTONG"); 380 return null; 381 } 382 }); 383 } 384 385 if(folder != null) { 386 folder.open(Folder.READ_WRITE); 387 } 388 389 return folder.getMessages(); 390 } 391 392 /** 393 * 过滤邮箱信息 394 * 395 * @param messages 396 * @param fromMail 只读取该邮箱发来的邮件,如果为空则不过滤 397 * @param startDate 只读取该日期以后的邮件,如果为空则不过滤 398 * @return 399 * @throws MessagingException 400 */ 401 public static List<Message> filterMessage(Message[] messages, String fromMail, String startDate) throws MessagingException, ParseException { 402 List<Message> messageList = new ArrayList<>(); 403 if (ObjectUtils.isEmpty(messages)) { 404 return messageList; 405 } 406 boolean isEnptyFromMail = ObjectUtils.isEmpty(fromMail); 407 boolean isEnptyStartDate = ObjectUtils.isEmpty(startDate); 408 if (isEnptyFromMail && isEnptyStartDate) { 409 return Arrays.asList(messages); 410 } 411 412 String from; 413 for (Message message: messages) { 414 from = (message.getFrom()[0]).toString(); 415 if (isEnptyFromMail) { 416 if (new SimpleDateFormat(NORM_DATETIME_PATTERN).parse(startDate).getTime() > message.getSentDate().getTime()) { 417 continue; 418 } 419 } else if (null != from && from.contains(fromMail)) { 420 if (!isEnptyStartDate && new SimpleDateFormat(NORM_DATETIME_PATTERN).parse(startDate).getTime() > message.getSentDate().getTime()) { 421 continue; 422 } 423 } else { 424 continue; 425 } 426 messageList.add(message); 427 } 428 return messageList; 429 } 430 431 /** 432 * 打印邮件 433 * 434 * @param messageList 435 * @throws IOException 436 * @throws MessagingException 437 */ 438 public static void printMailMessage(List<Message> messageList) throws IOException, MessagingException { 439 System.out.println("邮件数量:" + messageList.size()); 440 ShowMail re; 441 Message message; 442 for (int i = 0, leng = messageList.size(); i < leng; i++) { 443 message = messageList.get(i); 444 re = new ShowMail((MimeMessage) message); 445 System.out.println("邮件【" + i + "】主题:" + re.getSubject()); 446 System.out.println("邮件【" + i + "】发送时间:" + re.getSentDate()); 447 System.out.println("邮件【" + i + "】是否需要回复:" + re.getReplySign()); 448 System.out.println("邮件【" + i + "】是否已读:" + re.isNew()); 449 System.out.println("邮件【" + i + "】是否包含附件:" + re.isContainAttach( message)); 450 System.out.println("邮件【" + i + "】发送人地址:" + re.getFrom()); 451 System.out.println("邮件【" + i + "】收信人地址:" + re.getMailAddress("to")); 452 System.out.println("邮件【" + i + "】抄送:" + re.getMailAddress("cc")); 453 System.out.println("邮件【" + i + "】暗抄:" + re.getMailAddress("bcc")); 454 System.out.println("邮件【" + i + "】发送时间:" + re.getSentDate()); 455 System.out.println("邮件【" + i + "】邮件ID:" + ((MimeMessage) message).getMessageID()); 456 re.getMailContent(message); 457 System.out.println("邮件【" + i + "】正文内容: " + re.getBodyText()); 458 re.setAttachPath("D:\Download\mailFile\"); 459 re.saveAttachMent(message); 460 } 461 } 462 463 public static void main(String[] args) throws MessagingException, IOException, ParseException { 464 // 阿里云登录信息 465 // String host = "pop3.mxhichina.com"; 466 // String username = "liwei@xiaostudy.com"; 467 // String password = "密码"; 468 // String protocol = "pop3"; 469 // String fromMail = "XXX@163.com"; 470 // String startDate = "2020-2-24 23:35:40"; 471 // List<Message> messageList = filterMessage(getALiYunMessage(host, username, password, protocol), fromMail, startDate); 472 473 // 163登录信息 474 String host = "imap.163.com"; 475 String username = "XXX@163.com"; 476 String password = "授权码,不是密码"; 477 String protocol = "imaps"; 478 String fromMail = "liwei@xiaostudy.com"; 479 String startDate = "2020-2-24 23:35:40"; 480 List<Message> messageList = filterMessage(getWEMessage(host, username, password, protocol), fromMail, startDate); 481 482 printMailMessage(messageList); 483 } 484 }
参考文章:https://blog.csdn.net/qq_34173549/article/details/79661997
https://www.xuebuyuan.com/731341.html
3、163邮箱的imap协议的参考
这篇文章:https://www.cnblogs.com/shihaiming/p/10416383.html