JMail接收及解析邮件
前期准备工作
-
首先需要将邮箱开启POP3服务
以126邮箱为例,如图所示,开启POP3,加一个授权码并记住,记下最下面的POP3服务器地址
-
发送一封测试邮件
笔者这里用126邮箱发送了一封邮件(带附件)给qq邮箱,随后qq邮箱回复邮件(也带附件)给126邮箱,下文将读取126邮箱中收到的这封邮件。 -
引入Maven依赖
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
上代码
ReceiveEmailProcess 方法中有两个方法,processEmail方法传入三个参数,pop3主机(例如:pop.126.com),用户名,授权码,上文已提到。execute方法处理收件夹,具体义务逻辑在子类中重写。
package com.cong;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
public abstract class ReceiveEmailProcess {
public EmailParseResult processEmail(String pop3Host, String user, String password) {
Properties properties = new Properties();
properties.put("mail.store.protocol", "pop3");
properties.put("mail.pop3.host", pop3Host);
properties.put("mail.pop3.port", "995");
properties.put("mail.pop3.starttls.enable", "true");
Session emailSession = Session.getDefaultInstance(properties);
Folder emailFolder = null;
Store store = null;
EmailParseResult result = null;
try {
store = emailSession.getStore("pop3s");
store.connect(pop3Host, user, password);
emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
result = execute(emailFolder);
} catch (MessagingException e) {
e.printStackTrace();
} finally {
try {
emailFolder.close(false);
store.close();
} catch (MessagingException e) {
e.printStackTrace();
}
return result;
}
}
EmailParseResult execute(Folder emailFolder) {
throw new UnsupportedOperationException("execute method haven't implement.");
}
}
具体的业务逻辑类,其中可以获取到每一封邮件的title,发送时间,具体文本内容,附件等。
execute主要做过滤邮件,处理头信息。
parseEmail方法主要作解析邮件正文。
package com.cong;
import javax.mail.*;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.search.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
public class DownloadAttachmentProcess extends ReceiveEmailProcess{
@Override
EmailParseResult execute(Folder emailFolder) {
EmailParseResult result = null;
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DAY_OF_WEEK, -2);
Date twoDaysAgo = calendar.getTime();
// 过滤两天前之前且来自ONE_EMAIL_ADDRESS的邮件
SearchTerm filterTerm = new AndTerm(new FromStringTerm(${ONE_EMAIL_ADDRESS}),
new SentDateTerm(ComparisonTerm.LT, twoDaysAgo));
try {
result = new EmailParseResult();
Message[] messages = emailFolder.search(filterTerm);
System.out.println("messages.length---" + messages.length);
for (int i = 0; i < messages.length; i++) {
Message msg = messages[i];
String from = msg.getFrom()[0].toString();
if (from.startsWith("=?")) {
from = MimeUtility.decodeText(from);
}
String subject = msg.getSubject();
String sendDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(msg.getSentDate());
System.out.println("---------------------------------");
System.out.println("subject: " + subject);
System.out.println("from: " + from);
System.out.println("sendDate: " + sendDate);
System.out.println("msg ContentType: " + msg.getContentType());
System.out.println("msg MessageNumber: " + msg.getMessageNumber());
System.out.println("msg Message-ID: " + msg.getHeader("Message-ID")[0]);
parseEmail(msg);
result.setCode(EmailParseResult.SUCCESS).setSuccess(true).setMessage("parsed success!");
}
} catch (MessagingException e) {
e.printStackTrace();
result.setCode(EmailParseResult.FAILED).setSuccess(false).setMessage("parsed failed!");
} catch (IOException e) {
e.printStackTrace();
result.setCode(EmailParseResult.FAILED).setSuccess(false).setMessage("parsed failed!");
} finally {
return result;
}
}
void parseEmail(Message msg) throws MessagingException, IOException {
if (msg.isMimeType("multipart/**")) {
Multipart mp = (Multipart) msg.getContent();
System.out.println("mp.getCount()" + mp.getCount());
LinkedList<Multipart> mpList = new LinkedList<Multipart>();
mpList.add(mp);
for (int j = 0; j < mp.getCount(); ++j) {
BodyPart bp = mp.getBodyPart(j);
if (bp.getDisposition() != null) {
String fileName = bp.getFileName();
if (fileName.startsWith("=?")) {
fileName = MimeUtility.decodeText(fileName);
}
System.out.println("fileName: " + fileName);
File file = new File("G:\\out\\" + fileName);
file.createNewFile();
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
InputStream inputStream = bp.getInputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.close();
} else if (bp.isMimeType("text/plain")) {
System.out.println((String) bp.getContent());
} else if (bp.isMimeType("multipart/**")) {
// 既有附件,又有图片等嵌入资源时
MimeMultipart content = (MimeMultipart) bp.getContent();
for (int k = 0; k < mp.getCount(); ++k) {
BodyPart contentBodyPart = content.getBodyPart(k);
if (contentBodyPart.isMimeType("text/plain")) {
// 此处仅处理邮件的文本内容
System.out.println("multipart/** text/plain" + (String) contentBodyPart.getContent());
} else {
System.out.println("multipart/** !text/plain" + contentBodyPart.getContentType());
}
}
}
}
} else if (msg.isMimeType("text/plain")) {
System.out.println((String) msg.getContent());
} else {
System.out.println(msg.getContentType() + " 暂不支持 ");
}
}
}
简单做一个结果返回类
package com.cong;
public class EmailParseResult {
public static final int SUCCESS = 200;
public static final int FAILED = 500;
private boolean success;
private int code;
private String message;
public boolean isSuccess() {
return success;
}
public EmailParseResult setSuccess(boolean success) {
this.success = success;
return this;
}
public int getCode() {
return code;
}
public EmailParseResult setCode(int code) {
this.code = code;
return this;
}
public String getMessage() {
return message;
}
public EmailParseResult setMessage(String message) {
this.message = message;
return this;
}
@Override
public String toString() {
return "EmailParseResult{" +
"success=" + success +
", code=" + code +
", message='" + message + '\'' +
'}';
}
}
main类测试
package com.cong;
public class Starter {
public static void main(String[] args) {
String host = "pop.126.com";
String username = "${YOUR_EMAIL_ADDRESS}";
String password = "${AUTHORIZATION_CODE}"; // 授权码
EmailParseResult result = new DownloadAttachmentProcess().processEmail(host, username, password);
System.out.println(result);
}
}
测试结果
邮件正文和附件顺利拿到。