添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
获取邮件附件代码
package com.example.emaildemo.email;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import javax.mail.search.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
public class Pop3Mails {
public static void main(String[] args) {
Pop3Mails mail = new Pop3Mails();
mail.read();
}
public void read() {
Properties props = new Properties();
try {
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.pop3.socketFactory.fallback", "false");
props.setProperty("mail.pop3.port", "995");
props.setProperty("mail.pop3.socketFactory.port", "995");
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("pop3");
String user = "xxxx@gmail.com";
// 如果为gmail需开通二次验证密码
String password = "xxxxxx";
store.connect("pop.gmail.com", user, password);
Folder inbox = store.getFolder("inbox");
inbox.open(Folder.READ_ONLY);
LocalDateTime localDateTime = LocalDateTime.now().minusYears(1);
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = localDateTime.atZone(zoneId);//Combines this date-time with a time-zone to create a ZonedDateTime.
Date start = Date.from(zdt.toInstant());
Date now = new Date();
SearchTerm comparisonTermGe = new SentDateTerm(ComparisonTerm.GE, start);
SearchTerm comparisonTermLe = new SentDateTerm(ComparisonTerm.LE, now);
//需要查询的邮件名
String fromEmail = "xxxxxxxxxx@gmail.com";
FromStringTerm fromStringTerm = new FromStringTerm(fromEmail);
SearchTerm andTerm = new AndTerm(new SearchTerm[]{comparisonTermGe, comparisonTermLe});
Message[] messages = inbox.search(andTerm); //根据设置好的条件获取message
Message[] search = inbox.search(fromStringTerm, messages);
for (int i = search.length - 1; i >= 0; i--) {
Message message = search[i];
Date date = message.getSentDate();
System.out.println("Mail Subject:- " + message.getSubject());
System.out.println("Mail Content Type:- " + message.getContentType());
System.out.println("Mail Sent Date:- " + date);
if (message.getContentType().startsWith("multipart/")) {
needProcessEmail(message);
}
}
inbox.close(true);
store.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 文件拷贝,在用户进行附件下载的时候,可以把附件的InputStream传给用户进行下载
*
* @param is
* @param os
* @throws IOException
*/
public static void copy(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[1024];
int len = 0;
while ((len = is.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
if (os != null)
os.close();
if (is != null)
is.close();
}
private boolean needProcessEmail(Message msg) throws Exception {
System.out.println("needProcessEmail > 当前邮件的标题" + msg.getSubject());
// 1. 检查发件人邮箱是否包含在我们监控的邮箱列表里面
String from = getFrom(msg);
if (!isContainAttach((Part) msg)) {
System.out.println("发件人满足要求但是附件为空,不满足我们监控的需求!");
return false;
}
Map<String, InputStream> fileMap = new HashMap<>();
getFileInputStream(msg, fileMap);
if (fileMap.isEmpty()) {
System.out.println("尽管邮件中有附件但是邮件中的附件却无一个满足要求!");
return false;
}
System.out.println(fileMap);
for (String s : fileMap.keySet()) {
InputStream inputStream = fileMap.get(s);
copy(inputStream, new FileOutputStream("D:\\" + s));
}
return true;
}
private String getFrom(Message msg) throws MessagingException {
String from = "";
InternetAddress[] addresses = (InternetAddress[]) msg.getFrom();
if (null == addresses || addresses.length == 0) {
System.out.println("无法获取发送人地址信息");
return from;
}
Address address = addresses[0];
System.out.println("件人地址json:" + address);
String form = ((InternetAddress) address).getAddress();
return form;
}
private void getFileInputStream(Part part, Map<String, InputStream> inputStreamMap) throws Exception {
String fileName;
if (part.isMimeType("multipart/*")) {
Multipart mp = (Multipart) part.getContent();
for (int i = 0; i < mp.getCount(); i++) {
BodyPart mPart = mp.getBodyPart(i);
String disposition = mPart.getDisposition();
if ((disposition != null)
&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
.equals(Part.INLINE)))) {
fileName = mPart.getFileName();
if (fileName.toLowerCase().contains("gb2312")) {
fileName = MimeUtility.decodeText(fileName);
}
if (checkFileName(fileName)) {
inputStreamMap.put(fileName, mPart.getInputStream());
}
} else if (mPart.isMimeType("multipart/*")) {
System.out.println("子邮件里面的附件");
getFileInputStream(mPart, inputStreamMap);
} else {
fileName = mPart.getFileName();
if ((fileName != null)
&& (fileName.toLowerCase().contains("GB2312"))) {
fileName = MimeUtility.decodeText(fileName);
if (checkFileName(fileName)) {
inputStreamMap.put(fileName, mPart.getInputStream());
}
}
}
}
} else if (part.isMimeType("message/rfc822")) {
getFileInputStream((Part) part.getContent(), inputStreamMap);
}
}
private boolean checkFileName(String fileName) {
return true;
}
private boolean isContainAttach(Part part) throws Exception {
boolean attachFlag = false;
// String contentType = part.getContentType();
if (part.isMimeType("multipart/*")) {
Multipart mp = (Multipart) part.getContent();
for (int i = 0; i < mp.getCount(); i++) {
BodyPart mPart = mp.getBodyPart(i);
String disposition = mPart.getDisposition();
if ((disposition != null)
&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
.equals(Part.INLINE)))) {
attachFlag = true;
} else if (mPart.isMimeType("multipart/*")) {
attachFlag = isContainAttach((Part) mPart);
} else {
String conType = mPart.getContentType();
if (conType.toLowerCase().contains("application")) {
attachFlag = true;
}
if (conType.toLowerCase().contains("name")) {
attachFlag = true;
}
}
}
} else if (part.isMimeType("message/rfc822")) {
attachFlag = isContainAttach((Part) part.getContent());
}
return attachFlag;
}
}