JMail接受及解析邮件

JMail接收及解析邮件

前期准备工作

  1. 首先需要将邮箱开启POP3服务
    以126邮箱为例,如图所示,开启POP3,加一个授权码并记住,记下最下面的POP3服务器地址
    在这里插入图片描述

  2. 发送一封测试邮件
    在这里插入图片描述
    笔者这里用126邮箱发送了一封邮件(带附件)给qq邮箱,随后qq邮箱回复邮件(也带附件)给126邮箱,下文将读取126邮箱中收到的这封邮件。

  3. 引入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);
    }
}

测试结果

邮件正文和附件顺利拿到。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值