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()); // 解决附件中文名乱码问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?