java解析邮件并下载附件

2023-10-29

package com.testspring.mailserver.mail.parsemail;

import com.sun.mail.pop3.POP3Folder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.Properties;

@RestController
@RequestMapping("/mail")
public class ParseMailService {

    @RequestMapping("/parsemail")
    public void run(){
    	// 如邮箱地址为taotao@163.com ,则这里的名称只需要填taotao
    	// 授权码不等于密码,授权码获取,需要自行百度,qq邮箱有qq邮箱的方式,163有163的方式
        this.parsemail01("邮箱的名称","邮箱的授权码");
    }

    public void parsemail01(String mailname,String pwd){
        try{
            // 链接邮箱
            Session session = Session.getInstance(new Properties());
            Store store = session.getStore("pop3");
            // 这里163.com 可以更改,你用qq 或者其他邮箱,就更改其他的.com
            store.connect("pop3.163.com",110,mailname,pwd);
            Folder folder = store.getFolder("inbox");
            folder.open(Folder.READ_ONLY);
            Message message[] = folder.getMessages();
            POP3Folder inbox = (POP3Folder) folder;
            PraseMimeMessage pmm = null;
            System.out.println(" 正在收取邮箱" + mailname+ "的邮件,开始下载相应附件到本地");
            for(int i = message.length -1; i >= 0; i--){
             // 可在此地书写自己的业务逻辑
                pmm = new PraseMimeMessage((MimeMessage) message[i]);
                pmm = new PraseMimeMessage((MimeMessage) message[i]);
                System.out.println("Message " + i + " subject: " + pmm.getSubject());
                System.out.println("Message " + i + "  containAttachment: "+ pmm.isContainAttach((Part) message[i]));
                System.out.println("Message " + i + " form: " + pmm.getFrom());
                System.out.println("Message " + i + " to: "+ pmm.getMailAddress("to"));
                pmm.setDateFormat("yy年MM月dd日 HH:mm");
                pmm.getMailContent((Part) message[i]);
                System.out.println("Message " + i + " bodycontent: \r\n"+ pmm.getBodyText());
                File file = new File("e:\\tmp\\");
                if (!file.exists()) {
                    file.mkdirs();
                }
                pmm.setAttachPath(file.toString());
                pmm.saveAttachMent((Part) message[i]);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

邮箱工具类

package com.testspring.mailserver.mail.parsemail;

import java.io.*;
import java.text.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

public class PraseMimeMessage {
    private MimeMessage mimeMessage = null;
    private String saveAttachPath = "";// 附件下载后的存放目录
    private StringBuffer bodytext = new StringBuffer();
    // 存放邮件内容的StringBuffer对象
    private String dateformat = "yy-MM-dd HH:mm";// 默认的日前显示格式

    /**
     * 构造函数,初始化一个MimeMessage对象
     */
    public PraseMimeMessage() {
    }

    public PraseMimeMessage(MimeMessage mimeMessage) {
        this.mimeMessage = mimeMessage;
        System.out.println("create a PraseMimeMessage object........");
    }

    public void setMimeMessage(MimeMessage mimeMessage) {
        this.mimeMessage = mimeMessage;
    }

    /**
     * 获得发件人的地址和姓名
     */
    public String getFrom() throws Exception {
        InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
        String from = address[0].getAddress();
        if (from == null) from = "";
        String personal = address[0].getPersonal();
        if (personal == null) personal = "";
        String fromaddr = personal + "<" + from + ">";
        return fromaddr;
    }

    /**
     * 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同 "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
     */
    public String getMailAddress(String type) throws Exception {
        String mailaddr = "";
        String addtype = type.toUpperCase();
        InternetAddress[] address = null;
        if (addtype.equals("TO") || addtype.equals("CC") || addtype.equals("BCC")) {
            if (addtype.equals("TO")) {
                address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.TO);
            } else if (addtype.equals("CC")) {
                address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.CC);
            } else {
                address = (InternetAddress[]) mimeMessage.getRecipients(Message.RecipientType.BCC);
            }
            if (address != null) {
                for (int i = 0; i < address.length; i++) {
                    String email = address[i].getAddress();
                    if (email == null) email = "";
                    else {
                        email = MimeUtility.decodeText(email);
                    }
                    String personal = address[i].getPersonal();
                    if (personal == null) personal = "";
                    else {
                        personal = MimeUtility.decodeText(personal);
                    }
                    String compositeto = personal + "<" + email + ">";
                    mailaddr += "," + compositeto;
                }
                mailaddr = mailaddr.substring(1);
            }
        } else {
            throw new Exception("Error emailaddr type!");
        }
        return mailaddr;
    }

    /**
     * 获得邮件主题
     */
    public String getSubject() throws MessagingException {
        String subject = "";
        try {
            subject = MimeUtility.decodeText(mimeMessage.getSubject());
            if (subject == null) subject = "";
        } catch (Exception exce) {
        }
        return subject;
    }

    /**
     * 获得邮件发送日期
     */
    public String getSentDate() throws Exception {
        Date sentdate = mimeMessage.getSentDate();
        SimpleDateFormat format = new SimpleDateFormat(dateformat);
        return format.format(sentdate);
    }

    /**
     * 获得邮件正文内容
     */
    public String getBodyText() {
        return bodytext.toString();
    }

    /**
     * 解析邮件,把得到的邮件内容保存到一个StringBuffer对象中,解析邮件 主要是根据MimeType类型的不同执行不同的操作,一步一步的解析
     */
    public void getMailContent(Part part) throws Exception {
        String contenttype = part.getContentType();
        int nameindex = contenttype.indexOf("name");
        boolean conname = false;
        if (nameindex != -1) conname = true;
        System.out.println("CONTENTTYPE: " + contenttype);
        if (part.isMimeType("text/plain") && !conname) {
            bodytext.append((String) part.getContent());
        } else if (part.isMimeType("text/html") && !conname) {
            bodytext.append((String) part.getContent());
        } else if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();
            int counts = multipart.getCount();
            for (int i = 0; i < counts; i++) {
                getMailContent(multipart.getBodyPart(i));
            }
        } else if (part.isMimeType("message/rfc822")) {
            getMailContent((Part) part.getContent());
        } else {
        }
    }

    /**
     * 判断此邮件是否需要回执,如果需要回执返回"true",否则返回"false"
     */
    public boolean getReplySign() throws MessagingException {
        boolean replysign = false;
        String needreply[] = mimeMessage.getHeader("Disposition-Notification-To");
        if (needreply != null) {
            replysign = true;
        }
        return replysign;
    }

    /**
     * 获得此邮件的Message-ID
     */
    public String getMessageId() throws MessagingException {
        return mimeMessage.getMessageID();
    }

    /**
     * 【判断此邮件是否已读,如果未读返回返回false,反之返回true】
     */
    public boolean isNew() throws MessagingException {
        boolean isnew = false;
        Flags flags = ((Message) mimeMessage).getFlags();
        Flags.Flag[] flag = flags.getSystemFlags();
        System.out.println("flags's length: " + flag.length);
        for (int i = 0; i < flag.length; i++) {
            if (flag[i] == Flags.Flag.SEEN) {
                isnew = true;
                System.out.println("seen Message.......");
                break;
            }
        }
        return isnew;
    }

    /**
     * 判断此邮件是否包含附件
     */
    public 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().indexOf("application") != -1)
                        attachflag = true;
                    if (contype.toLowerCase().indexOf("name") != -1)
                        attachflag = true;
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            attachflag = isContainAttach((Part) part.getContent());
        }
        return attachflag;
    }

    /**
     * 【保存附件】
     */
    public void saveAttachMent(Part part) 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().indexOf("gb2312") != -1) {
                        fileName = MimeUtility.decodeText(fileName);
                    }else {
                        fileName = MimeUtility.decodeWord(fileName);
                    }
                    saveFile(fileName, mpart.getInputStream());
                } else if (mpart.isMimeType("multipart/*")) {
                    saveAttachMent(mpart);
                } else {
                    fileName = mpart.getFileName();
                    if ((fileName != null) && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
                        fileName = MimeUtility.decodeText(fileName);
                        saveFile(fileName, mpart.getInputStream());
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            saveAttachMent((Part) part.getContent());
        }
    }

    /**
     * 【设置附件存放路径】
     */
    public void setAttachPath(String attachpath) {
        this.saveAttachPath = attachpath;
    }

    /**
     * 【设置日期显示格式】
     */
    public void setDateFormat(String format) throws Exception {
        this.dateformat = format;
    }

    /**
     * 【获得附件存放路径】
     */
    public String getAttachPath() {
        return saveAttachPath;
    }

    /**
     * 【真正的保存附件到指定目录里】
     */
    private void saveFile(String fileName, InputStream in) throws Exception {
        String osName = System.getProperty("os.name");
        String storedir = getAttachPath();
        String separator = "";
        if (osName == null) osName = "";
        if (osName.toLowerCase().indexOf("win") != -1) {
            separator = "\\";
            if (storedir == null || storedir.equals(""))
                storedir = "c:\\tmp";
        } else {
            separator = "/";
            storedir = "/tmp";
        }
        File storefile = new File(storedir + separator + fileName);
        System.out.println("storefile's path: " + storefile.toString());
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(storefile));
            bis = new BufferedInputStream(in);
            int c;
            while ((c = bis.read()) != -1) {
                bos.write(c);
                bos.flush();
            }
        } catch (Exception exception) {
            exception.printStackTrace();
            throw new Exception("文件保存失败!");
        } finally {
            bos.close();
            bis.close();
        }
    }
}


程序执行之后,会将邮件内的附件下载到本地,如需要解析它或者读成流的形式入库,则需要用不同的方式自行实现。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java解析邮件并下载附件 的相关文章

  • 使用 Intellij Idea 和 gradle 在应用程序引擎上调试 localhost

    我正在使用 IntelliJ 社区添加并使用 Gradle 构建应用程序引擎标准环境应用程序 在迁移到 IntelliJ 和端点框架之前 我使用的是 Android Studio 我无法调试我的本地主机 我添加了 jvmFlags 如下所述
  • 在java中轮询Http服务器(重复发送http get请求)

    当对其进行 REST 调用时 我的 Web 服务器会发送一些信息 我想不断轮询该服务器 间隔5秒后重复发送HTTP GET请求 以检查返回的信息是否有任何变化 做到这一点最有效的方法是什么 您能提供一些代码示例吗 请注意 我只想开发客户端代
  • 我是否需要安装 SQLite 才能使 SQLiteJDBC 正常工作?

    我想我只是没有 明白 如果我的计算机上尚未安装 SQLite 并且我想编写一个使用嵌入式数据库的 Java 应用程序 并且我将 SQLiteJDBC JAR 下载 导入到我的项目中 那么这就是我所需要的吗 或者 我是否需要先安装 SQLit
  • 有没有创建 Cron 表达式的 Java 代码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要一个 Java 代码来根据用户输入创建一个 cron 表达式 用户输入是时间 频率和执行次数 只需从评论中添加 自己创建 即可
  • Java Logger 未记录到 Netbeans 中的输出

    我正在 Netbeans 中使用 Maven 启动一个 Java 项目 我编写了一些代码来使用 Logger 类进行日志记录 但是 日志记录似乎不起作用 在程序开始时 我运行 Logger getLogger ProjectMainClas
  • 如何在java中将数组值排序为循环格式?

    我的数组值如下 String value 1 2 3 4 5 6 7 8 9 10 假设如果我将值 5 传递给 tat 数组 它应该按如下顺序排序 5 6 7 8 9 10 1 2 3 4 怎么办 有人帮忙吗 感谢你 你需要的就是所谓的轮换
  • 两个整数乘积的模

    我必须找到c c a b mod m a b c m 是 32 位整数 但 a b 可以超过 32 位 我正在尝试找出一种计算 c 的方法 而不使用 long 或任何 gt 32 位的数据类型 有任何想法吗 如果m是质数 事情可以简化吗 注
  • 与 Eclipse 中的 Java Content Assist 交互

    作为我的插件项目的一部分 我正在考虑与 Eclipse 在 Java 文件上显示的内容辅助列表进行交互 我正在尝试根据一些外部数据对列表进行重新排序 我看过一些有关创建新内容辅助的教程 但没有看到有关更改现有内容辅助的教程 这可能吗 如果是
  • 如何在 Java 中向时间戳添加/减去时区偏移量?

    我正在使用 JDK 8 并且玩过ZonedDateTime and Timestamp很多 但我仍然无法解决我面临的问题 假设我得到了格式化的Timestamp在格林威治标准时间 UTC 我的服务器位于某处 假设它设置为Asia Calcu
  • Jframe 内有 2 个 Jdialogs 的 setModal 问题

    当我设置第一个选项时 我遇到了问题JDialog模态 第二个非模态 这是我正在尝试实现的功能 单击 测试对话框 按钮 一个JDialog有名字自定义对话框 主要的将会打开 如果单击 是 选项自定义对话框主 其他JDialog named 自
  • 断言 Kafka 发送有效

    我正在使用 Spring Boot 编写一个应用程序 因此要写信给 Kafka 我这样做 Autowired private KafkaTemplate
  • Java 中如何将 char 转换为 int? [复制]

    这个问题在这里已经有答案了 我是Java编程新手 我有例如 char x 9 我需要得到撇号中的数字 即数字 9 本身 我尝试执行以下操作 char x 9 int y int x 但没有成功 那么我应该怎么做才能得到撇号中的数字呢 ASC
  • Sun 在 EDT 之外做 GUI 工作的演示?

    我正在看SplashDemo java http download oracle com javase tutorial uiswing examples misc SplashDemoProject src misc SplashDemo
  • Jetty、websocket、java.lang.RuntimeException:无法加载平台配置器

    我尝试在 Endpoint 中获取 http 会话 我遵循了这个建议https stackoverflow com a 17994303 https stackoverflow com a 17994303 这就是我这样做的原因 publi
  • 如何将 HTML 链接放入电子邮件正文中?

    我有一个可以发送邮件的应用程序 用 Java 实现 我想在邮件中放置一个 HTML 链接 但该链接显示为普通字母 而不是 HTML 链接 我怎样才能将 HTML 链接放入字符串中 我需要特殊字符吗 太感谢了 Update 大家好你们好 感谢
  • 不可变的最终变量应该始终是静态的吗? [复制]

    这个问题在这里已经有答案了 在java中 如果一个变量是不可变的并且是final的 那么它应该是一个静态类变量吗 我问这个问题是因为每次类的实例使用它时创建一个新对象似乎很浪费 因为无论如何它总是相同的 Example 每次调用方法时都会创
  • 将 JScrollPane 添加到 JFrame

    我有一个关于向 Java 框架添加组件的问题 我有一个带有两个按钮的 JPanel 和一个添加了 JTable 的 JScrollPane 我想将这两个添加到 JFrame 中 我可以将 JPanel 添加到 JFrame 或将 JScro
  • 在java中以原子方式获取多个锁

    我有以下代码 注意 为了可读性 我尽可能简化了代码 如果我忘记了任何关键部分 请告诉我 public class User private Relations relations public User relations new Rela
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • 由 Servlet 容器提供服务的 WebSocket

    上周我研究了 WebSockets 并对如何使用 Java Servlet API 实现服务器端进行了一些思考 我没有花费太多时间 但在使用 Tomcat 进行一些测试时遇到了以下问题 如果不修补容器或至少对 HttpServletResp

随机推荐

  • 和泉纱雾

    和泉纱雾 Time Limit 1000 ms Memory Limit 65536 KiB Submit Statistic Problem Description 众所周知 和泉纱雾是著名的埃罗芒阿老师 画画功力首屈一指 今天我们的埃罗
  • 长度大小为零的数组(柔性数组、可变数组)

    书山有路勤为径 学海无涯苦作舟 目录 前言 一 什么是柔性数组 二 柔性数组应用及优势对比 1 定长数组 2 指针域 3 柔性数组 总结 前言 柔性数组 Arrays of Length Zero 是GNU GCC在C C 标准下扩展而引出
  • 网络测速命令

    linux命令行测速 https blog 51cto com 13718210 2418661
  • C语言课程设计-工资管理系统

    前言 这个程序是博主在大学第一个学期学完C语言后的课程设计 那时刚从一个小白变得会一点点编程 老师就布置了这个课程设计 当时一脸懵这是啥 我在哪 我要干什么 但是通过查阅了很多资料以及问了许多人以后 我逐渐开始写我的第一个项目 现在来看这个
  • opencv_gpu加速环境配置教程问题汇总

    1 安装CUDA 1 1 安装的cuda版本与英伟达驱动中的版本必须是一致的 1 2 安装的cuda后必须把cuda的环境配置到系统的环境变量中 1 3 检查cuda安装的版本与英伟达版本是不是一致的 cmd中输入 nvcc V 2 安装o
  • IDEA 怎么自定义代码模板?

    打开idea gt File gt Settings 点击 Editor gt Live Templates 添加组名或组的变量名 输入自己定义的变量名 即可输出代码 点击 Edit variables Expression改为与自己代码需
  • 使用sersync实现数据实时同步

    使用sersync实现数据实时同步 sersync诞生过程 部署前提 配置rsync服务端 部署sersync 配置sersync的path变量 修改sersync配置文件 sersync常用参数 使用服务文件实现开机自启动 实时同步服务d
  • vue中postcss怎么配置

    主要是 postcssrc js中的配置 在进入主题之前先记录下node中读取文件路径的问题 node js中的文件路径主要是包括 dirname filename process cwd 等 前面三个是绝对路径 后面是相对路径 当然你可以
  • Java API之Calendar(日历)类[详解]

    Calendar 日历 类 一 Calendar概述 位于java util Caleandar包中 是一个抽象基类 用于完成日期字段之间相互转换的功能 由于是抽象类型 因此不可直接实例化 不能new 对象 一个Caleandar类的实例是
  • CSS简介

    CSS简介 什么是CSS CSS 是层叠样式表 Cascading Style Sheets 的简称 有时我们也会称之为 CSS 样式表或级联样式表 CSS 是也是一种标记语言 CSS 主要用于设置 HTML 页面中的文本内容 字体 大小
  • 【排序】快速排序

    思路分析 快速排序采用双向查找的策略 每一趟选择当前所有子序列中的一个关键字作为枢纽轴 将子序列中比枢纽轴小的前移 比枢纽轴大的后移 当本趟所有子序列都被枢轴按上述规则划分完毕后将会得到新的一组更短的子序列 他们将成为下趟划分的初始序列集
  • WARN:Establishing SSL connection without server’s identity verification is not recommended

    在JAVA WEB项目中做到C3P0数据库连接池部分运行Java代码时候出现一大片红色报错警告 Establishing SSL connection without server s identity verification is no
  • 【概率论与数理统计】猴博士 笔记 p24-25 条件概率密度函数、求两个随机变量形成的函数的分布

    条件概率密度函数 题型如下 已知概率密度 求条件概率密度 已知x怎么样的情况下y服从的概率 或y怎么样的情况下x服从的概率 求f x y 步骤 对于后两个 是在哪个字母的条件下 哪个字母就在后面 即 如果是在x 的条件下 那么就选图中第三条
  • LeetCode 283. 移动零(C++)

    1 题目如下 给定一个数组 nums 编写一个函数将所有 0 移动到数组的末尾 同时保持非零元素的相对顺序 请注意 必须在不复制数组的情况下原地对数组进行操作 示例 1 这里是引用 输入 nums 0 1 0 3 12 输出 1 3 12
  • mac生成linux下可执行的.go二进制文件

    在项目的根目录下使用下面命令 env GOOS linux GOARCH amd64 go build o 指定文件名 main go
  • elasticsearch 后置过滤器(Post Filter)

    本章翻译自Elasticsearch官方指南的Filtering Queries and Aggregations一章 过滤查询以及聚合 A natural extension to aggregation scoping is filte
  • AC-DC--------单相可控整流电路

    带电阻负载的工作情况 原理图 波形图 在分析整流电路工作时 认为晶闸管 开关器件 为理想器件 即晶闸管导通时其管压降等于零 晶闸管阻断时其漏电流等于零 除非特意研究晶闸管的开通 关断过程 一般认为晶闸管的开通与关断过程瞬时完成 工作原理 改
  • 基本流程图与跨职能流程图

    流程可以用流程图来表示 但它们有一个缺点 标准流程图无法表明谁负责这些活动 流程可以用流程图来表示 但它们有一个缺点 标准流程图无法表明谁负责这些活动 因此 跨职能流程图 或称为泳道图 泳道流程图 跨职能流程图 通过定义谁做什么来使流程更加
  • Ajax中get请求和post请求的区别

    Ajax中请求方式有get和post两种 二者的区别可以从传参方式 请求头以及参数类型来进行比较 post请求 get请求 区别 1 传参方式 get请求在url的尾部传递参数 而post请求在send方法中传递参数 2 请求头 post请
  • java解析邮件并下载附件

    package com testspring mailserver mail parsemail import com sun mail pop3 POP3Folder import org springframework web bind