荒野剧场

Java imap邮件接收与解析

邮件结构

一个Message的content可以是纯文本,也可以是MimeMultipart

MimeMultipart mimeMultipart = new MimeMultipart();
message.setContent(mimeMultipart);

message.setContent("纯文本正文", "text/plain");

一个MimeMultipart可以包含多个MultipartBody

MimeMultipart mimeMultipart = new MimeMultipart();
mimeMultipart.addBodyPart();

MultipartBody可以设置内容,比如邮件正文,也可以包含文件作为邮件附件

body.setContent("邮件正文", "text/*");

body.setDataHandler(new DataHandler(new FileDataSource(tempFile)));
body.setFileName("smile.jpg");

接收、解析邮件

Properties props = new Properties();
props.setProperty("mail.transport.protocol", "imap"); // 使用的协议, imap | pop3
props.setProperty("mail.imap.host", "smtp.qq.com"); // 邮箱的收件服务器地址

// 获取连接
Session session = Session.getDefaultInstance(props);
session.setDebug(false);

IMAPStore store = (IMAPStore) session.getStore(protocol);
store.connect(emailboxServer, username, authCode); // imap服务器的登录认证, 邮箱账号用户名,授权码
IMAPFolder inbox = (IMAPFolder) store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
Message[] messages = inbox.getMessages();

for (Message message : messages) {
    IMAPMessage imapMessage = (IMAPMessage) message;
    Flags flags = imapMessage.getFlags();
    if (flags.contains(Flags.Flag.SEEN)) {
        continue;
    }

    CustomerEmail email = new CustomerEmail();
    email.setEmailId(inbox.getUID(imapMessage)); // 邮件唯一标识
    email.setDeliveryDate(format.format(imapMessage.getSentDate())); // 发件日期
    String subject = imapMessage.getSubject(); // 主题
    email.setSubject(subject);
    InternetAddress from = (InternetAddress) imapMessage.getFrom()[0]; // 发件人
    email.setFrom(from.getAddress());
    InternetAddress to = (InternetAddress) imapMessage.getReplyTo()[0]; // 收件人
    email.setTo(to.getAddress());
    if (message.isMimeType("TEXT/*")) { // 仅包含正文的简单邮件
        System.out.println("邮件正文: " + message.getContent());
    } else {
        parseMessage((MimeMultipart) message.getContent()); // 解析稍复杂邮件
    }
}

/**
 * 解析邮件
 */
public static void parseMessage (MimeMultipart part) throws MessagingException, IOException {
    byte[] bytes = new byte[1024];
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();

    for (int i = 0; i < part.getCount(); i++) {
        BodyPart body = part.getBodyPart(i);
        if (body.isMimeType("text/html")) {
            System.out.println("html格式正文: " + (String) body.getContent());
        } else if (body.isMimeType("text/plain")) {
            System.out.println("纯文本格式正文: " + (String) body.getContent());
        } else if (body.isMimeType("multipart/*")) {
            MimeMultipart multipart = (MimeMultipart) body.getContent();
            parseMessage(multipart);
        } else { // 附件
            InputStream inputStream = body.getDataHandler().getInputStream();
            int len = 0;
            while( (len = inputStream.read(bytes)) != -1 ){
                outStream.write(bytes, 0, len);
            }
            inputStream.close();
            byte[] data = outStream.toByteArray();
            String fileName = body.getFileName();
            File tempFile = new File(FileUtils.getTempDirectoryPath() + File.separator + System.currentTimeMillis() + fileName );
            FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
            fileOutputStream.write(data);
            fileOutputStream.close();
            System.out.println("邮件附件本地路径: " + tempFile.getAbsolutePath());
        }
    }
}


/**
 * 构造邮件
*/
public static MimeMessage constructEmail (Session session, String from, String to, String subject, String content, MultipartFile[] fileList, List<String> tempFilePathList) throws MessagingException, IOException {
    MimeMessage mimeMessage = new MimeMessage(session);

    // 发件人
    mimeMessage.setFrom(new InternetAddress(from));
    // 收件人
    mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
    // 邮件标题
    mimeMessage.setSubject(subject);

    // 邮件内容
    // 准备图片数据
//        MimeBodyPart image = new MimeBodyPart();
//        DataHandler handler = new DataHandler(new FileDataSource("C:\\Users\\wild theater\\Desktop\\R-C.jpg"));
//        image.setDataHandler(handler);
//        image.setContentID("test.png"); //设置图片id

//        appendix.setDataHandler(new DataHandler(new FileDataSource("C:\\Users\\wild theater\\Desktop\\运营海卖报表.docx")));
//        appendix.setFileName("运营海卖报表.docx");


    // 邮件正文部分
    MimeBodyPart text = new MimeBodyPart();
    text.setContent(content, "text/html;charset=utf-8");
    MimeMultipart contentPart = new MimeMultipart();
//        mimeMultipart.addBodyPart(image);
    contentPart.addBodyPart(text);
//        mimeMultipart.setSubType("related"); // 文本和图片内嵌成功
    MimeBodyPart contentBody = new MimeBodyPart();
    contentBody.setContent(contentPart);

    // 拼接正文、附件
    MimeMultipart allFile = new MimeMultipart();
    allFile.addBodyPart(contentBody); // 正文
    
    // 拼接多个附件
    if (fileList != null && fileList.length > 0) {
        for (MultipartFile file : fileList) {
            MimeBodyPart attachedFile = new MimeBodyPart();
            // 创建临时文件存放附件数据
            String filename = "customerEmail" + System.currentTimeMillis();
            String filePath = FileUtils.getTempDirectoryPath() + TEMP_DIRECTORY_NAME + File.separator + filename;
            File tempFile = new File(filePath);
            FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);
            attachedFile.setDataHandler(new DataHandler(new FileDataSource(tempFile)));
            attachedFile.setFileName(file.getOriginalFilename());
            allFile.addBodyPart(attachedFile);
        }
    }

    allFile.setSubType("mixed"); // 正文和附件都存在邮件中,所有类型设置为mixed

    // 放到Message消息中
    mimeMessage.setContent(allFile);
    mimeMessage.saveChanges();

    return mimeMessage;
}

解决附件中文名乱码问题

InputStream inputStream = body.getDataHandler().getInputStream();
String fileName = MimeUtility.decodeText(body.getFileName()); // 解决附件中文名乱码问题

posted on 2022-08-26 14:41  荒野剧场  阅读(1936)  评论(0编辑  收藏  举报

导航