使用Javamail接收imaps协议的邮件

网上的消息不能说大多,只能说基本都过时了,连imap和imaps都不分了

本文基于apache-james项目搭建的邮件服务器,其他邮件服务器仅供参考

首先是依赖,这里需要引入两个依赖,如下

    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>javax.mail-api</artifactId>
      <version>1.6.2</version>
    </dependency>
    <dependency>
      <groupId>com.sun.mail</groupId>
      <artifactId>javax.mail</artifactId>
      <version>1.6.2</version>
    </dependency>

代码部分,这是SSL的情况

    @Test
    void receive(){
        IMAPStore store = null;
        IMAPFolder folder = null;
        try{
            // 准备登录信息:
            String host = "serverIP";
            int port = 993;
            String username = "test@example.com";
            String password = "password";
            final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
            // 这里的Provider不会自动补全,而且写好之后是红色字体表示报错,idea会提示解决方案
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            // 设置信任所有证书,仅限测试环境,正式环境需要去掉,否则证书安全性形同虚设
            MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
            socketFactory.setTrustAllHosts(true);

            Properties props = new Properties();
            props.put("mail.imaps.socketFactory", socketFactory);
            props.put("mail.imaps.socketFactory.class", SSL_FACTORY);
            props.put("mail.imaps.socketFactory.port", port);
            props.put("mail.store.protocol", "imaps");
            props.put("mail.imaps.host", host);
            props.put("mail.imaps.port", port);
            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });
            store = (IMAPStore) session.getStore("imaps");
            store.connect();

            // INBOX指收件箱
            folder = (IMAPFolder) store.getFolder("INBOX");// 获得用户的邮件帐户
            folder.open(Folder.READ_WRITE); // 设置对邮件帐户的访问权限

            Message[] messages = folder.getMessages();// 得到邮箱帐户中的所有邮件

            for (Message message : messages) {
                for(Part part: getBody(message)){
                    System.out.println(part.getContent());
                }
            }
        }catch (MessagingException | IOException | GeneralSecurityException e) {
            e.printStackTrace();
        } finally{
            try{
                assert folder != null;
                folder.close(true);// 关闭邮件夹对象
                store.close(); // 关闭连接对象
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    }

这里有一个getBody方法,参考 https://www.liaoxuefeng.com/wiki/1252599548343744/1319099948859426#0 做了一些优化,一个MimeMessage对象也是一个Part对象,它可能只包含一个文本,也可能是一个Multipart对象,即由几个Part构成,因此,需要递归地解析出完整的正文

List<Part> getBody(Part part) throws MessagingException, IOException {
        List<Part> body = new ArrayList<>();
        if (part.isMimeType("text/*")) {
            // Part是文本:
            body.add(part);
        }
        if (part.isMimeType("multipart/*")) {
            // Part是一个Multipart对象:
            Multipart multipart = (Multipart) part.getContent();
            // 循环解析每个子Part:
            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);
                if (!body.isEmpty()) {
                    body.addAll(getBody(bodyPart));
                }
            }
        }
        return body;
    }

如果收件服务器没有用ssl,去掉这三行,并且把所有的imaps改成imap

            props.put("mail.imaps.socketFactory", socketFactory);
            props.put("mail.imaps.socketFactory.class", SSL_FACTORY);
            props.put("mail.imaps.socketFactory.port", port);

欢迎留言交流

posted @ 2024-01-22 13:23  青索  阅读(634)  评论(0)    收藏  举报