springboot 收取邮件带有图片处理

embedded/2024/9/24 9:48:46/

1.遇到的问题

邮件中带有图片的,part中含有cid的,可以从party下载,图片和附件要保存到自己的存储服务器。

邮件获取图片MailUtil 工具类 

package com.esoon.cat.cc.email.utils.common;import com.alibaba.fastjson.JSONObject;
import jakarta.mail.MessagingException;
import jakarta.mail.Part;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;
import java.util.List;/*** @ClassName MailUtil* @Description TODO* @Author Jiangnan Cui* @Date 2024-09-12 19:03* @Version 1.0*/
public class MailUtil {private static final Logger logger = LoggerFactory.getLogger(MailUtil.class);/*** 邮件拿到Cid*/public static String getCid(Part p) throws MessagingException {String[] headers = p.getHeader("Content-ID");String content;if ((headers != null) && (headers.length > 0))content = headers[0];elsereturn null;String cid;if ((content.startsWith("<")) && (content.endsWith(">")))cid = "cid:" + content.substring(1, content.length() - 1);else {cid = "cid:" + content;}return cid;}/*** 判断是否包含"<img src=\"cid:"*/public static boolean  isCidImgAndReplace(String text) {if (StringUtils.isBlank(text)) {return false;}return text.contains("<img src=\"cid:");}/*** 邮件将Cid替换为Url*/public static String replaceImgPathByCid(String content, List<String> cidList, List<String> attachments) {logger.info("#####判断正文是否含有<img src>" + isCidImgAndReplace(content));if (isCidImgAndReplace(content)) {for (int i = 0; i < cidList.size(); i++) {logger.info("#####邮件mail content cidList:"+ cidList);String oldSrc = cidList.get(i);logger.info("#####邮件mail content attachments:"+attachments.toString());String newSrc = attachments.get(i);logger.info("#####邮件mail content oldSrc:{},attachments newSrc:{}",oldSrc,newSrc);content = content.replace(oldSrc, newSrc);}}return content;}
}

2.邮件处理

StringBuffer content = new StringBuffer(30);
//处理邮件内容信息
//邮件中带图片Idlist
List<String> cidList=new ArrayList<>();
//邮件中带图片转化后的实际路径
List<String> attachmentsList = new ArrayList<>();getMailTextContent(msg, content,cidList,attachmentsList);
String mailAllContent;
if(cidList!=null && cidList.size()>0 && !attachmentsList.isEmpty()){List<String> attachmentsListNew = new ArrayList<>();for(String attach:attachmentsList){attachmentsListNew.add(storageDownLoadUrl+attach);}mailAllContent = MailUtil.replaceImgPathByCid(content.toString(),cidList,attachmentsListNew);

}

3.解析邮件内容 

/*** 获得邮件文本内容** @param part    邮件体* @param content 存储邮件文本内容的字符串* @throws MessagingException* @throws IOException*/
public  void getMailTextContent(Part part, StringBuffer content,List<String> cidList,List<String> attachList) throws MessagingException, IOException {//如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;if (part.isMimeType("text/*") && !isContainTextAttach) {content.append(part.getContent().toString());String cid=MailUtil.getCid(part);logger.info("#####getMailTextContent text/* cid:{} part MimeType:{}",cid);if(StringUtils.isNotEmpty(cid)) {cidList.add(cid);saveImageFile(part, attachmentDirectory, attachList);}} else if (part.isMimeType("message/rfc822")) {String cid=MailUtil.getCid(part);logger.info("#####getMailTextContent message/rfc822 cid:{}",cid);if(StringUtils.isNotEmpty(cid)) {cidList.add(cid);saveImageFile(part, attachmentDirectory, attachList);}getMailTextContent((Part) part.getContent(), content,cidList,attachList);} else if (part.isMimeType("multipart/*")) {Multipart multipart = (Multipart) part.getContent();int partCount = multipart.getCount();for (int i = 0; i < partCount; i++) {BodyPart bodyPart = multipart.getBodyPart(i);String cid=MailUtil.getCid(bodyPart);logger.info("#####getMailTextContent multipart/* cid:{}",cid);if(StringUtils.isNotEmpty(cid)) {cidList.add(cid);saveImageFile(bodyPart, attachmentDirectory, attachList);}getMailTextContent(bodyPart, content, cidList, attachList);}}
}

4.存储图片到自己的服务器

/*** 保存正文中有图片的** @param part    邮件中多个组合体中的其中一个组合体* @param destDir 附件保存目录* @throws UnsupportedEncodingException* @throws MessagingException* @throws IOException*/
public List<String> saveImageFile(Part part, String destDir, List<String> fileNames) {try {String fileName = part.getFileName();logger.info("######saveImageFile fileName={}", fileName);if (StringUtils.isNotEmpty(fileName)) {logger.info("######saveImageFile fileName={},decodeText={}", fileName, decodeText(part.getFileName()));InputStream is = part.getInputStream();if (fileName.toLowerCase().endsWith(".jpg") || fileName.toLowerCase().endsWith(".jpeg") || fileName.toLowerCase().endsWith(".png")) {String type = FilenameUtils.getExtension(decodeText(part.getFileName()));String fileKey = createFileKey() + (StringUtils.isEmpty(type) ? "" : "." + type);String filePath = destDir + File.separator + fileKey.substring(0, 10) + File.separator + fileKey;logger.info("######saveImageFile fileKey={},filePath={}", fileKey, filePath);try {createFileToNas(filePath, is);} catch (IOException e) {createFileToNas(filePath, is);logger.error("######createFileToNas error:{}", e);}fileNames.add(fileKey);}}}catch (Exception ex){logger.error("#####saveImageFile error:{}",ex);}return fileNames;
}

5.总结

邮件解析的方式差不多,需要根据实际情况出发做解析。 


http://www.ppmy.cn/embedded/116033.html

相关文章

2024ICPC网络赛第一场C. Permutation Counting 4(线性代数)

题目链接 题目大意&#xff1a;给你n个范围[ l i , r i l_i,r_i li​,ri​]&#xff0c;每个位置可以在这个范围中选择一个数&#xff0c;然后形成排列1到n的排列p。问p的所有情况的个数的奇偶性。 一个很妙的行列式转化&#xff0c;纯纯的线性代数。 首先&#xff0c;我们把…

排序算法C++

冒泡排序 冒泡排序是一种简单直观的排序算法&#xff0c;它通过多次遍历列表&#xff0c;逐步将最大&#xff08;或最小&#xff09;的元素“冒泡”到列表的末尾。其名称源于算法的运行方式&#xff1a;较大的元素逐渐向上浮动&#xff0c;就像水中的气泡一样。 工作原理 遍…

ChatGPT 推出“Auto”自动模式:智能匹配你的需求

OpenAI 最近为 ChatGPT 带来了一项新功能——“Auto”自动模式&#xff0c;这一更新让所有用户无论使用哪种设备都能享受到更加个性化的体验。简单来说&#xff0c;当你选择 Auto 模式后&#xff0c;ChatGPT 会根据你输入的提示词复杂程度&#xff0c;自动为你挑选最适合的AI模…

生物信息学中的pipeline到底是什么?

在生物信息学中&#xff0c;pipeline&#xff08;管道或工作流程&#xff09;是指一系列自动化的计算步骤&#xff0c;用来处理、分析生物数据。由于生物信息学涉及大量复杂且多步骤的数据分析过程&#xff0c;pipeline 的出现大大提高了分析效率和结果的可重复性。 Pipeline的…

鸿蒙_异步详解

参考详细链接&#xff1a; 鸿蒙HarmonyOS异步并发开发指南

使用Hutool-poi封装Apache POI进行Excel的上传与下载

介绍 Hutool-poi是针对Apache POI的封装&#xff0c;因此需要用户自行引入POI库,Hutool默认不引入。到目前为止&#xff0c;Hutool-poi支持&#xff1a; Excel文件&#xff08;xls, xlsx&#xff09;的读取&#xff08;ExcelReader&#xff09;Excel文件&#xff08;xls&…

java逃逸分析

概念 对象逃逸分析&#xff1a;是一种有效减少Java程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析&#xff0c;Java虚拟机能够分析出一个新的对象的引用范围从而决定是否要将这个对象分配到堆上。Java1.7后默认开启逃逸分析的选项。Java的JIT编译器…

微服务--Gateway网关

在微服务架构中&#xff0c;Gateway&#xff08;网关&#xff09;是一个至关重要的组件&#xff0c;它扮演着多种关键角色&#xff0c;包括路由、负载均衡、安全控制、监控和日志记录等。 Gateway网关的作用 统一访问入口&#xff1a; Gateway作为微服务的统一入口&#xff0c…