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.总结
邮件解析的方式差不多,需要根据实际情况出发做解析。