java 收发邮件(带附件发送和附件解析)

1.java 发送邮件
收发邮件所需要的jar包。

<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>

1.1 发送不带附件的邮件

/**
     * 发送邮件 不包含附件
     * @param toEmail 接受人邮箱
     * @param fromEmail 发送人邮箱
     * @param password 发送人密码
     */
    public static void sendEmaile(String toEmail,String fromEmail,String password) {
        try {
            Properties props = new Properties();
            //smtp保持不变,.后面改为邮箱后缀  eg:smtp.qq.com
            String host = "smtp.sea-level.com.cn";
            props.put("mail.smtp.host", host); // SMTP主机名
            props.put("mail.smtp.auth", "true"); // 是否需要用户认证
            props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密
            // 获取Session实例:
            Session session = Session.getInstance(props, new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(fromEmail, password);
                }
            });
            MimeMessage message = new MimeMessage(session);
            // 设置发送方地址:
            message.setFrom(new InternetAddress(fromEmail));
            // 设置接收方地址:
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
            // 设置邮件主题:
            message.setSubject("Hello", "UTF-8");
            // 设置邮件正文:这是普通邮件
            message.setText("Hi 这是一份来自javamail 邮件", "UTF-8");
            // 发送:
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

注:host 一定要根据自己的真实邮箱修改哦。
1.2 发送带附件的邮件

/**
     * 发送邮件 包含附件
     * @param toEmail
     * @param fromEmail
     * @param password
     */
    public static void sendEmailForFile(String toEmail,String fromEmail,String password){
        try {
            Properties props = new Properties();
            String host = "smtp.sea-level.com.cn";
            props.put("mail.smtp.host", host); // SMTP主机名
            props.put("mail.smtp.auth", "true"); // 是否需要用户认证
            //props.put("mail.smtp.port", "587"); // 主机端口号
            props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密
            // 获取Session实例:
            Session session = Session.getInstance(props, new Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(fromEmail, password);
                }
            });
            MimeMessage message = new MimeMessage(session);
            // 设置发送方地址:
            message.setFrom(new InternetAddress(fromEmail));
            // 设置接收方地址:
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
            // 设置邮件主题:
            message.setSubject("Hello", "UTF-8");
            // 设置邮件正文:这是含有附件的邮件
            Multipart multipart = new MimeMultipart();
            // 添加text:
            BodyPart textpart = new MimeBodyPart();
            String body ="这是一个带有附件的邮件,请注意查收附件";
            textpart.setContent(body, "text/html;charset=utf-8");
            multipart.addBodyPart(textpart);
            // 添加附件: 直接发送内容
           /* BodyPart filepart = new MimeBodyPart();
            String fileName ="附件.txt";
            filepart.setFileName(fileName);
            //input 在附件中写入内容
            String input ="这里居然是文件的内容";
            try {
                filepart.setDataHandler(new DataHandler(new ByteArrayDataSource(input, "application/octet-stream")));
            } catch (IOException e) {
                e.printStackTrace();
            }
            multipart.addBodyPart(filepart);*/
           //发送邮件,发送本地文件
            BodyPart filepart = new MimeBodyPart();
            String fileName ="附件.txt";
            filepart.setFileName(fileName);
            //path 要发送的本地文件的路径
            String path ="d:\\file01.txt";
            FileDataSource fileDataSource = new FileDataSource(path);
            filepart.setDataHandler(new DataHandler(fileDataSource));
            multipart.addBodyPart(filepart);
            // 设置邮件内容为multipart:
            message.setContent(multipart);
            // 发送:
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

注:附件有两种方式,一种直接往附件里写内容,一种是发送本地存在的文件,按照提示进行放开相应的注释就可以了哦。
在本地使用main() 方法就可以测试。
2.接受邮件,并且读取附件内容

package com.hzm;

import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;

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

/**
 * @Author:huangzhimin
 * @Date:2020/7/30
 * @描述:这里只处理未读邮件,并能够获取邮件中的附件
 **/
public class ImapEmail {
    public static void main(String[] args) throws Exception{
        String user = "*******";// 邮箱的用户名
        String password = "****"; // 邮箱的密码

        Properties prop = System.getProperties();
        prop.put("mail.store.protocol", "imap");
        //此处也有修改为 内网邮箱后缀 eg: imap.qq.com
        prop.put("mail.imap.host", "imap.sea-level.com.cn");

        Session session = Session.getInstance(prop);
        // 使用imap会话机制,连接服务器
        IMAPStore store = (IMAPStore) session.getStore("imap");
        //链接邮箱
        store.connect(user, password);
        // 收件箱
        IMAPFolder folder = (IMAPFolder) store.getFolder("INBOX");
        //以只读的模式打开
        folder.open(Folder.READ_ONLY);
        // 获取总邮件数
        int  total = folder.getMessageCount();
        System.out.println("-----------------共有邮件:" + total + " 封--------------");
        System.out.println("未读邮件数:" + folder.getUnreadMessageCount());
        //获取收件箱中的所有邮件
        Message[] messages = folder.getMessages();
        for (Message message : messages) {
            //获取邮件的状态
            Flags flags = message.getFlags();
            //获取未读的邮件内容
            if (!flags.contains(Flags.Flag.SEEN)) {
                System.out.println("发送时间:" + message.getSentDate());
                System.out.println("主题:" + message.getSubject());
                String subject =  message.getSubject();
                System.out.println("内容: "+getBody((MimeMessage)message));
                System.out.println("附件详细信息:");
                getFileInputStream((MimeMessage)message);
                //System.out.println("附件:"+getFileInputStream((MimeMessage)message));
                //对指定的邮件进行解析 对指定主题的邮件设置已读
                if(subject.equals("READ_ONLY")){
                    System.out.println("开始执行解析程序");
                    //将邮件设置为已读
                    message.setFlag(Flags.Flag.SEEN,true);
                }
            }

        }
    }

    public static String getBody(Part part) throws MessagingException, IOException {
        if (part.isMimeType("text/*")) {
            return part.getContent().toString();
        }
        if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();
            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);
                String body = getBody(bodyPart);
                if (!body.isEmpty()) {
                    return body;
                }
            }
        }
        return "";
    }

    public static void getFileInputStream(Part part) throws Exception{
        if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();

            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);
                String disposition = bodyPart.getDisposition();
                String fileName = null;
                //说明有附件
                if((disposition != null) && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))){
                    fileName = bodyPart.getFileName();
                    System.out.println("附件名称"+fileName);
                    //获取附件的流
                    System.out.println("大小为:" + bodyPart.getSize());
//                    InputStream inputStream = bodyPart.getInputStream();
//                    //全量读出
//                    int size = bodyPart.getSize();
//                    byte[] buffer = new byte[size];
//                    inputStream.read(buffer);
//                    System.out.println("附件内容是:"+new String (buffer));
                    //按行读出
                    BufferedReader in = new BufferedReader(new InputStreamReader(bodyPart.getInputStream()));
                    String line = null;
                    while (( line = in.readLine())!= null ){
                        System.out.println("this line:"+ line);
                        line = null;
                    }
                    //inputStream.close();
                    in.close();

                }
            }
        }
    }
}

本文只读取未读邮件的内容,和附件内容。如果想获取全部邮件的内容,修改if判断条件即可。
同时对指定主题的邮件进行读取,和解析后将邮件设置为已读状态。
注:邮件收取 有pop3 协议 和IMAP 协议,本文使用的是IMAP 协议。pop3协议无法区分邮件是否已读,同时无法将已读之类的操作提交到邮箱服务器,IMAP 使用更加便捷。