springboot发邮件,javaxmail收邮件功能

简介: springboot发邮件,javaxmail收邮件功能


import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.protocol.IMAPProtocol;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.util.ObjectUtils;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class ReceivedIMAPMail {

public static String NORM_DATETIME_PATTERN = "yyyy-MM-dd hh:mm:ss";

private MimeMessage mimeMessage;
/**
 * 附件下载后的存放目录
 */
private String saveAttachPath = "";
/**
 * 存放邮件内容的StringBuffer对象
 */
private StringBuffer bodyText = new StringBuffer();

/**
 * 构造函数,初始化一个MimeMessage对象
 *
 * @param mimeMessage
 */
public ReceivedIMAPMail(MimeMessage mimeMessage) {
    this.mimeMessage = mimeMessage;
}

/**
 * 获得发件人的地址和姓名
 *
 * @return
 * @throws MessagingException
 */
public String getFrom() throws MessagingException {
    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 = null;
    if (personal != null || from != null) {
        fromAddr = personal + "<" + from + ">";
    }
    return fromAddr;
}

/**
 * 获得邮件的收件人,抄送,和密送的地址和姓名,根据所传递的参数的不同
 *
 * @param type "to"----收件人 "cc"---抄送人地址 "bcc"---密送人地址
 * @return
 * @throws MessagingException
 * @throws UnsupportedEncodingException
 */
public String getMailAddress(String type) throws MessagingException, UnsupportedEncodingException {
    if (ObjectUtils.isEmpty(type)) {
        return "";
    }

    String addType = type.toUpperCase();

    if (!addType.equals("TO") && !addType.equals("CC") && !addType.equals("BCC")) {
        return "";
    }
    InternetAddress[] address;

    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 (ObjectUtils.isEmpty(address)) {
        return "";
    }
    StringBuilder mailAddr = new StringBuilder();
    String emailAddr;
    String personal;
    for (int i = 0; i < address.length; i++) {
        emailAddr = address[i].getAddress();
        if (emailAddr == null) {
            emailAddr = "";
        } else {
            emailAddr = MimeUtility.decodeText(emailAddr);
        }
        personal = address[i].getPersonal();
        if (personal == null) {
            personal = "";
        } else {
            personal = MimeUtility.decodeText(personal);
        }
        mailAddr.append(",").append(personal).append("<").append(emailAddr).append(">");
    }
    return mailAddr.toString().substring(1);
}

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

/**
 * 获得邮件发送日期
 *
 * @return
 * @throws MessagingException
 */
public String getSentDate() throws MessagingException {
    Date sentDate = mimeMessage.getSentDate();
    SimpleDateFormat format = new SimpleDateFormat(NORM_DATETIME_PATTERN);
    return format.format(sentDate);
}

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

/**
 * 解析邮件,把得到的邮件内容保存到一个StringBuffer对象中,解析邮件 主要是根据MimeType类型的不同执行不同的操作,一步一步的解析
 * 
 * @param part
 * @throws MessagingException
 * @throws IOException
 */
public void getMailContent(Part part) throws MessagingException, IOException {

    String contentType = part.getContentType();

    int nameIndex = contentType.indexOf("name");

    boolean conName = false;

    if (nameIndex != -1) {
        conName = true;
    }

    if (part.isMimeType("text/plain") && conName == false) {
        bodyText.append((String) part.getContent());
    } else if (part.isMimeType("text/html") && conName == false) {
        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++) {
            this.getMailContent(multipart.getBodyPart(i));
        }
    } else if (part.isMimeType("message/rfc822")) {
        this.getMailContent((Part) part.getContent());
    }
}

/**
 * 判断此邮件是否需要回执,如果需要回执返回"true",否则返回"false"
 *
 * @return
 * @throws MessagingException
 */
public boolean getReplySign() throws MessagingException {

    boolean replySign = false;

    String needReply[] = mimeMessage.getHeader("Disposition-Notification-To");

    if (needReply != null) {
        replySign = true;
    }
    return replySign;
}

/**
 * 判断此邮件是否已读,如果未读返回false,反之返回true
 *
 * @return
 * @throws MessagingException
 */
public boolean isNew() throws MessagingException {
    boolean isNew = false;
    Flags flags = mimeMessage.getFlags();
    Flags.Flag[] flag = flags.getSystemFlags();
    for (int i = 0; i < flag.length; i++) {
        if (flag[i] == Flags.Flag.SEEN) {
            isNew = true;
        }
    }
    return isNew;
}

/**
 * 判断此邮件是否包含附件
 *
 * @param part
 * @return
 * @throws MessagingException
 * @throws IOException
 */
public boolean isContainAttach(Part part) throws MessagingException, IOException {
    boolean attachFlag = false;
    if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        BodyPart mPart;
        String conType;
        for (int i = 0; i < mp.getCount(); i++) {
            mPart = mp.getBodyPart(i);
            String disposition = mPart.getDisposition();
            if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) {
                attachFlag = true;
            } else if (mPart.isMimeType("multipart/*")) {
                attachFlag = this.isContainAttach(mPart);
            } else {
                conType = mPart.getContentType();
                if (conType.toLowerCase().indexOf("application") != -1
                        || conType.toLowerCase().indexOf("name") != -1) {
                    attachFlag = true;
                }
            }
        }
    } else if (part.isMimeType("message/rfc822")) {
        attachFlag = isContainAttach((Part) part.getContent());
    }
    return attachFlag;
}

/**
 * 保存附件
 *
 * @param part
 * @throws MessagingException
 * @throws IOException
 */
public void saveAttachMent(Part part) throws MessagingException, IOException {
    String fileName;
    if (part.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) part.getContent();
        BodyPart mPart;
        for (int i = 0; i < mp.getCount(); i++) {
            mPart = mp.getBodyPart(i);
            String disposition = mPart.getDisposition();
            if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) {
                fileName = mPart.getFileName();
                if (null != fileName && fileName.toLowerCase().indexOf("gb2312") != -1) {
                    fileName = MimeUtility.decodeText(fileName);
                }
                fileName = fileName.replaceAll("\\?|=", "");
                this.saveFile(fileName, mPart.getInputStream());
            } else if (mPart.isMimeType("multipart/*")) {
                this.saveAttachMent(mPart);
            } else {
                fileName = mPart.getFileName();
                if ((fileName != null) && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
                    fileName = MimeUtility.decodeText(fileName);
                    this.saveFile(fileName, mPart.getInputStream());
                }
            }
        }
    } else if (part.isMimeType("message/rfc822")) {
        this.saveAttachMent((Part) part.getContent());
    }
}

/**
 * 设置附件存放路径
 *
 * @param attachPath
 */
public void setAttachPath(String attachPath) {
    this.saveAttachPath = attachPath;
}

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

/**
 * 真正的保存附件到指定目录里
 *
 * @param fileName
 * @param in
 * @throws IOException
 */
private void saveFile(String fileName, InputStream in) throws IOException {
    String osName = System.getProperty("os.name");
    String storeDir = this.getAttachPath();
    if (null == osName) {
        osName = "";
    }
    if (osName.toLowerCase().indexOf("win") != -1) {
        if (ObjectUtils.isEmpty(storeDir))
            storeDir = "C:\\tmp";
    } else {
        storeDir = "/tmp";
    }
    FileOutputStream fos = new FileOutputStream(new File(storeDir + File.separator + fileName));
    IOUtils.copy(in, fos);
    IOUtils.closeQuietly(fos);
    IOUtils.closeQuietly(in);
}

/**
 * 获取阿里云邮箱信息
 *
 * @param host     邮件服务器
 * @param username 邮箱名
 * @param password 密码
 * @param protocol 协议
 * @return
 * @throws MessagingException
 */
public static Message[] getALiYunMessage(String host, String username, String password, String protocol)
        throws MessagingException {
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);

    Store store = session.getStore(protocol);
    store.connect(host, username, password);

    Folder folder = store.getFolder("INBOX");
    folder.open(Folder.READ_ONLY);
    return folder.getMessages();
}

/**
 * 获取163邮箱信息
 *
 * @param host
 * @param username
 * @param password
 * @param protocol
 * @return
 * @throws MessagingException
 */
public static Message[] getWEMessage(String host, String username, String password, String protocol)
        throws MessagingException {
    Properties props = System.getProperties();
    props.setProperty("mail.store.protocol", protocol);
    Session session = Session.getDefaultInstance(props, null);
    Store store = session.getStore(protocol);
    store.connect(host, username, password);
    Folder folder = store.getFolder("INBOX");

    if (folder instanceof IMAPFolder) {
        IMAPFolder imapFolder = (IMAPFolder) folder;
        // javamail中使用id命令有校验checkOpened, 所以要去掉id方法中的checkOpened();
        imapFolder.doCommand(new IMAPFolder.ProtocolCommand() {
            public Object doCommand(IMAPProtocol p) throws com.sun.mail.iap.ProtocolException {
                Map<String, String> gmap = new HashMap<>();
                gmap.put("GUID", "FUTONG");
                // p.id("FUTONG");
                p.id(gmap);
                return null;
            }
        });
    }

    if (folder != null) {
        folder.open(Folder.READ_WRITE);
    }

    return folder.getMessages();
}

/**
 * 过滤邮箱信息
 *
 * @param messages
 * @param fromMail  只读取该邮箱发来的邮件,如果为空则不过滤
 * @param startDate 只读取该日期以后的邮件,如果为空则不过滤
 * @return
 * @throws MessagingException
 */
public static List<Message> filterMessage(Message[] messages, String fromMail, String startDate)
        throws MessagingException, ParseException {
    List<Message> messageList = new ArrayList<>();
    if (ObjectUtils.isEmpty(messages)) {
        return messageList;
    }
    boolean isEnptyFromMail = ObjectUtils.isEmpty(fromMail);
    boolean isEnptyStartDate = ObjectUtils.isEmpty(startDate);
    if (isEnptyFromMail && isEnptyStartDate) {
        return Arrays.asList(messages);
    }

    String from;
    for (Message message : messages) {
        from = (message.getFrom()[0]).toString();
        if (isEnptyFromMail) {
            if (new SimpleDateFormat(NORM_DATETIME_PATTERN).parse(startDate).getTime() > message.getSentDate()
                    .getTime()) {
                continue;
            }
        } else if (null != from && from.contains(fromMail)) {
            if (!isEnptyStartDate && new SimpleDateFormat(NORM_DATETIME_PATTERN).parse(startDate)
                    .getTime() > message.getSentDate().getTime()) {
                continue;
            }
        } else {
            continue;
        }
        messageList.add(message);
    }
    return messageList;
}

/**
 * 打印邮件
 *
 * @param messageList
 * @throws IOException
 * @throws MessagingException
 */
public static void printMailMessage(List<Message> messageList) throws IOException, MessagingException {
    System.out.println("邮件数量:" + messageList.size());
    ReceivedIMAPMail re;
    Message message;
    for (int i = 0, leng = messageList.size(); i < leng; i++) {
        message = messageList.get(i);
        re = new ReceivedIMAPMail((MimeMessage) message);
        System.out.println("邮件【" + i + "】主题:" + re.getSubject());
        System.out.println("邮件【" + i + "】发送时间:" + re.getSentDate());
        System.out.println("邮件【" + i + "】是否需要回复:" + re.getReplySign());
        System.out.println("邮件【" + i + "】是否已读:" + re.isNew());
        System.out.println("邮件【" + i + "】是否包含附件:" + re.isContainAttach(message));
        System.out.println("邮件【" + i + "】发送人地址:" + re.getFrom());
        System.out.println("邮件【" + i + "】收信人地址:" + re.getMailAddress("to"));
        System.out.println("邮件【" + i + "】抄送:" + re.getMailAddress("cc"));
        System.out.println("邮件【" + i + "】暗抄:" + re.getMailAddress("bcc"));
        System.out.println("邮件【" + i + "】发送时间:" + re.getSentDate());
        System.out.println("邮件【" + i + "】邮件ID:" + ((MimeMessage) message).getMessageID());
        re.getMailContent(message);
        // System.out.println("邮件【" + i + "】正文内容:\r\n" + re.getBodyText());
        if(re.isContainAttach(message)) {
            System.out.println("邮件包含附件,开始下载到D:\\xl下面");
            re.setAttachPath("D:\\xl\\mail\\");
            re.saveAttachMent(message);
        }
    }
}

public static void main(String[] args) throws MessagingException, IOException, ParseException {
    // 阿里云登录信息

// String host = "pop3.mxhichina.com";
// String username = "liwei@xiaostudy.com";
// String password = "密码";
// String protocol = "pop3";
// String fromMail = "XXX@163.com";
// String startDate = "2020-2-24 23:35:40";
// List messageList = filterMessage(getALiYunMessage(host, username, password, protocol), fromMail, startDate);

    // 163登录信息
    String host = "imap.163.com";
    String username = "*****@163.com";
    String password = "客户端授权码";
    String protocol = "imaps";
    String fromMail = "";// "****@163.com";
    String startDate = "";// "2020-2-24 23:35:40";
    List<Message> messageList = filterMessage(getWEMessage(host, username, password, protocol), fromMail,
            startDate);

    printMailMessage(messageList);
}

}

相关文章
|
5天前
|
存储 Java 分布式数据库
Spring Boot 优雅实现hbase功能
【6月更文挑战第24天】要在 Spring Boot 项目中实现 HBase 和 Memcached 的功能,首先需要理解各自的原理和作用,然后通过实际操作将其集成到 Spring Boot 项目中。
25 6
|
5天前
|
Java 应用服务中间件 Maven
Springboot入门基础知识详解 parent starter 引导类 辅助功能
Springboot入门基础知识详解 parent starter 引导类 辅助功能
13 2
|
9天前
|
安全 Java Maven
在 Spring Boot 中实现邮件发送功能可以通过集成 Spring Boot 提供的邮件发送支持来完成
在 Spring Boot 中实现邮件发送功能可以通过集成 Spring Boot 提供的邮件发送支持来完成
17 2
|
9天前
|
缓存 监控 安全
在 Spring Boot 中使用 AOP(Aspect-Oriented Programming)实现日志记录功能
在 Spring Boot 中使用 AOP(Aspect-Oriented Programming)实现日志记录功能
19 1
|
1天前
|
缓存 NoSQL Java
Spring Boot中集成Redis实现缓存功能
Spring Boot中集成Redis实现缓存功能
|
1天前
|
XML 负载均衡 Java
Spring Boot 中实现负载均衡:概念、功能与实现
【6月更文挑战第28天】在分布式系统中,负载均衡(Load Balancing)是指将工作负载和流量分配到多个服务器或服务实例上,以提高系统可用性和响应速度。负载均衡器可以是硬件设备,也可以是软件解决方案。
6 0
|
1天前
|
Java 机器人 程序员
Spring Boot中如何实现邮件发送功能
Spring Boot中如何实现邮件发送功能
|
2天前
|
Java Spring 容器
在Spring Boot中实现类似SPI机制的功能(二)
在Spring Boot中实现类似SPI机制的功能(二)
|
4天前
|
Java
springboot使用邮件服务
springboot使用邮件服务
11 0
|
5天前
|
Java 数据安全/隐私保护
Springboot拓展之整合邮件 JavaMail的使用与实操
Springboot拓展之整合邮件 JavaMail的使用与实操
5 0