使用JavaMail实现收取和回复邮件

您所在的位置:网站首页 最新qq自动回复 使用JavaMail实现收取和回复邮件

使用JavaMail实现收取和回复邮件

2023-08-05 01:41| 来源: 网络整理| 查看: 265

最近项目实现了一个使用javaMail来实现邮箱邮件的读取和邮件回复。本人查阅资料并汇总做个记录。

需要提前了解邮件协议 收取邮箱邮件的协议主要有两个,第一个是pop3,第二个是imap协议。两者协议唯一区别就是pop3不能识别邮箱邮件是否为已读需要自己去判断,而imap就很轻松做到这一点。我在这里选择imap协议发送协议选择smtp协议 常见邮箱类型的协议

我们项目不能确定客户到底使用什么类型的邮箱,所以自己单独测试了各类型的邮箱做个汇总,省的再去翻阅资料查询。注意:以下邮箱密码如果是授权码,需要单独查询各类型邮箱获取授权码的方式!如果是密码则直接使用邮箱密码即可!

QQ邮箱

imap服务器:imap.qq.com smtp服务器:smtp.qq.com smtp端口:587 用户名:账号名称 密码:授权码

企业邮箱

imap服务器:imap.exmail.qq.com smtp服务器:smtp.exmail.qq.com smtp端口:25 用户名:账号名称 密码:密码

新浪邮箱

imap服务器:imap.sina.com smtp服务器:smtp.sina.com smtp端口:25 用户名:账号名称 密码:授权码

outlook邮箱

imap服务器:outlook.office365.com smtp服务器:smtp-mail.outlook.com smtp端口:587 用户名:账号名称 密码:密码

163邮箱

imap服务器:imap.163.com smtp服务器:smtp.163.com smtp端口:25 用户名:账号名称 密码:授权码

139邮箱

139邮箱: imap服务器:imap.139.com smtp服务器:smtp.139.com smtp端口:25

** 阿里云邮箱 **

阿里云邮箱: imap服务器:imap.aliyun.com smtp服务器:smtp.aliyun.com smtp端口:25 用户名:账号名称 密码:密码

接下来不多BB,直接上代码(代码里的带前后~~ ~~格式的需要自己去填写具体的协议、账号、密码 )

收取邮件 /** 1. 读取邮件 */ public void readEmail() { Properties props = new Properties(); props.put("mail.imap.host", "~~imapHost~~ "); props.put("mail.imap.auth", "true"); props.setProperty("mail.store.protocol", "imap"); props.put("mail.imap.starttls.enable", "true"); Session session = Session.getInstance(props); try { Store store = session.getStore(); store.connect("~~imapHost~~ ","~~userName~~ ", "~~passWord~~ "); Folder folder = store.getFolder("Inbox"); //javamail中使用id命令有校验checkOpened, 所以要去掉id方法中的checkOpened();(这里针对163邮箱无法收发票做的逻辑代码) IMAPFolder imapFolder = (IMAPFolder)folder; imapFolder.doCommand(p -> { p.id("FUTONG"); return null; }); //邮箱打开方式 folder.open(Folder.READ_WRITE); //收取未读邮件 Message[] messages = folder.getMessages(folder.getMessageCount() - folder.getUnreadMessageCount() + 1, folder.getMessageCount()); //解析邮件 if (messages.length != 0) { parseMessage(messages); } //设置邮件为已读 folder.setFlags(messages, new Flags(Flags.Flag.SEEN), true); folder.close(true); store.close(); } catch (MessagingException e) { e.printStackTrace(); } } /** * 解析邮件 */ public void parseMessage(Message[] messages) { for (Message message : messages) { try { //获取未读邮件 if (!message.getFlags().contains(Flags.Flag.SEEN)) { MimeMessage mimeMsg = (MimeMessage) message; //判断邮件是否包含附件 boolean containAttachment = this.containAttachment(mimeMsg); // 解析邮件发件人 EmailInfo emailInfo = this.processEmailInfo(mimeMsg); log.debug("-----> 发件人信息:{}, 包含附件:{}", emailInfo, containAttachment); if (containAttachment) { // 邮箱附件解析 List mimeFileList = this.getMimeFile(mimeMsg); // 附件操作(遍历可以拿到每个文件的名称和流) saveEmailAttach(mimeFileList); } } } catch (MessagingException e) { e.printStackTrace(); } } } /** * 邮件是否包含附件 */ public static boolean containAttachment(MimeMessage mimeMsg) { try { if (mimeMsg.isMimeType(MULTIPART_MIME_TYPE)) { Multipart mp = (Multipart) mimeMsg.getContent(); for (int i = 0; i < mp.getCount(); i++) { BodyPart bp = mp.getBodyPart(i); // 如果该BodyPart对象包含附件 if (bp.getDisposition() != null) { return true; } } } } catch (MessagingException | IOException e) { log.error("-----> {}", LogUtil.stackTraceInfo(e)); } return false; } /** * 解析邮件发件信息 */ public static EmailInfo processEmailInfo(MimeMessage mimeMsg) { EmailInfo emailInfo = new EmailInfo(); try { String from = ((InternetAddress) (mimeMsg.getFrom()[0])).getAddress(); String subject = mimeMsg.getSubject(); Date sentDate = mimeMsg.getSentDate(); emailInfo.setFrom(from) .setSubject(subject) .setSendDate(sentDate) .setSendDateStr(DateUtil.format(sentDate, DatePattern.NORM_DATETIME_PATTERN)); } catch (MessagingException e) { log.error("-----> {}", LogUtil.stackTraceInfo(e)); } return emailInfo; } /** * 解析邮件附件 * * @param part 邮件中多个组合体中的其中一个组合体 */ public static List getMimeFile(Part part) { List files = new ArrayList(); try { if (part.isMimeType(MULTIPART_MIME_TYPE)) { //复杂体邮件 Multipart multipart = (Multipart) part.getContent(); //复杂体邮件包含多个邮件体 int partCount = multipart.getCount(); for (int i = 0; i < partCount; i++) { //获得复杂体邮件中其中一个邮件体 BodyPart bodyPart = multipart.getBodyPart(i); //某一个邮件体也有可能是由多个邮件体组成的复杂体 String disp = bodyPart.getDisposition(); if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) { files.add(bodyPart); } else if (bodyPart.isMimeType(MULTIPART_MIME_TYPE)) { getFile(bodyPart); } else { String contentType = bodyPart.getContentType(); if (contentType.contains("name") || contentType.contains("application")) { files.add(bodyPart); } } } } else if (part.isMimeType(RFC822_MIME_TYPE)) { getMimeFile((BodyPart) part.getContent()); } } catch (IOException | MessagingException e) { log.error("-----> {}", LogUtil.stackTraceInfo(e)); } return files; } /** * 保存附件 */ public void saveEmailAttach(List bodyPartList) { ArrayList attachList = new ArrayList(); try { for (BodyPart file : bodyPartList) { String fileNameSuffix = file.getFileName(); fileNameSuffix = MimeUtility.decodeText(fileNameSuffix); String suffix = fileNameSuffix.substring(fileNameSuffix.lastIndexOf(".") + 1); suffix = MimeUtility.decodeText(suffix); //判断附件类型是否为PDF(看具体情况具体处理) if (!suffix.equalsIgnoreCase("PDF")) { continue; } //获取输入流 InputStream inputStream = file.getInputStream(); //TODO } } catch (MessagingException | IOException e) { throw new CommonException(e); } } /** * 发件人信息 */ public class EmailInfo { /** 发件人 */ private String from; /** 主题 */ private String subject; /** 发件时间 */ private Date sendDate; /** 发件时间字符串 */ private String sendDateStr; } 2. 回复邮件 /** * @param smtpHost 邮箱服务器地址 * @param smtpPort 邮箱服务器端口 * @param userName 邮箱用户名 * @param password 邮箱密码 * @param sendAddr 发送地址(多个收件人以逗号分割) * @param subject 邮件主题 * @param message 邮件内容 * @param attr_path 附件(文件地址) */ private void sendMsg(String smtpHost, String smtpPort, String userName, String password, String sendAddr, String subject, String message, String attr_path) { try { Properties props = new Properties(); // 开启debug调试 props.setProperty(EmailConstant.MAIL_DEBUG, EmailConstant.FALSE); // 发送服务器需要身份验证 props.setProperty(EmailConstant.MAIL_SMTP_AUTH, EmailConstant.TRUE); // 设置邮件服务器主机名 log.info("----->回复邮件邮箱的服务器配置" + smtpHost); props.setProperty(EmailConstant.MAIL_HOST, smtpHost); // 发送邮件协议名称 props.setProperty(EmailConstant.MAIL_TRANSPORT_PROTOCOL, EmailConstant.SMTP); log.info("----->回复邮件的服务器端口配置" + smtpPort); props.setProperty(EmailConstant.MAIL_SMTP_PORT, smtpPort); props.put(EmailConstant.MAIL_SMTP_STARTTLS_ENABLE, EmailConstant.TRUE); props.put(EmailConstant.MAIL_SMTP_SSL_TRUST, smtpHost); props.put(EmailConstant.MAIL_SMTP_CONNECT_TIMEOUT, EmailConstant.MAIL_IMAP_TIMEOUT_VALUE); props.put(EmailConstant.MAIL_SMTP_TIMEOUT, EmailConstant.MAIL_IMAP_TIMEOUT_VALUE); props.put(EmailConstant.MAIL_SMTP_WRITE_TIMEOUT, EmailConstant.MAIL_IMAP_TIMEOUT_VALUE); // 设置环境信息 Session session = Session.getInstance(props); // 创建邮件对象 MimeMessage msg = new MimeMessage(session); // 设置发件人 msg.setFrom(new InternetAddress(userName)); // 设置收件人 String[] result = sendAddr.split(","); InternetAddress[] sendTo = new InternetAddress[result.length]; for (int i = 0; i < result.length; i++) { log.info("----->需发送到邮箱{}:" + result[i]); sendTo[i] = new InternetAddress(result[i]); } msg.addRecipients(Message.RecipientType.TO, sendTo); // 设置邮件主题 msg.setSubject(subject); //新建一个存放信件内容的BodyPart对象 BodyPart mdp = new MimeBodyPart(); //给BodyPart对象设置内容和格式/编码方式 mdp.setContent(message, EmailConstant.MESSAGE); //新建一个MimeMultipart对象用来存放BodyPart对象(事实上可以存放多个) Multipart mm = new MimeMultipart(); //将BodyPart加入到MimeMultipart对象中(可以加入多个BodyPart) mm.addBodyPart(mdp); if (StrUtil.isNotEmpty(attr_path)) { DataSource attr_ds = new FileDataSource(new File(attr_path)); DataHandler attr_handler = new DataHandler(attr_ds); BodyPart attachmentBodyPart = new MimeBodyPart(); attachmentBodyPart.setDataHandler(attr_handler); attachmentBodyPart.setFileName(MimeUtility.encodeWord(attr_path.substring(attr_path.lastIndexOf("/") + 1))); mm.addBodyPart(attachmentBodyPart); } //把mm作为消息对象的内容 msg.setContent(mm); Transport transport = session.getTransport(); // 连接邮件服务器 log.info("----->连接收票邮箱" + userName); transport.connect(userName, password); // 发送邮件 log.info("----->发送回复邮件"); transport.sendMessage(msg, sendTo); // 关闭连接 transport.close(); } catch (Exception e) { log.error("----->回复邮件异常{}", LogUtil.stackTraceInfo(e)); } } public class EmailConstant { public static String MAIL_IMAP_HOST = "mail.imap.host"; public static String MAIL_IMAP_AUTH = "mail.imap.auth"; public static String MAIL_STORE_PROTOCOL = "mail.store.protocol"; public static String MAIL_IMAP_STARTTLS_ENABLE = "mail.imap.starttls.enable"; public static String MAIL_IMAP_CONNECT_TIMEOUT = "mail.imap.connectiontimeout"; public static String MAIL_IMAP_TIMEOUT = "mail.imap.timeout"; public static String MAIL_IMAP_WRITE_TIMEOUT = "mail.imap.writetimeout"; public static String MAIL_SMTP_CONNECT_TIMEOUT = "mail.smtp.connectiontimeout"; public static String MAIL_SMTP_TIMEOUT = "mail.smtp.timeout"; public static String MAIL_SMTP_WRITE_TIMEOUT = "mail.smtp.writetimeout"; public static String MAIL_DEBUG = "mail.debug"; public static String MAIL_SMTP_AUTH = "mail.smtp.auth"; public static String MAIL_HOST = "mail.host"; public static String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol"; public static String MAIL_SMTP_PORT = "mail.smtp.port"; public static String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable"; public static String MAIL_SMTP_SSL_TRUST = "mail.smtp.ssl.trust"; public static String MESSAGE = "text/html;charset=UTF-8"; public static int MAIL_IMAP_TIMEOUT_VALUE = 5000; public static String MAIL_SPECIAL = "@163.com"; public static String MAIL_IMAP_SSL_TRUST = "mail.imap.ssl.trust"; public static String MAIL_IMAP_SSL_SOCKETFACTORY = "mail.imap.ssl.socketFactory"; public static String IMAP = "imap"; public static String SMTP = "smtp"; public static String TRUE = "true"; public static String FALSE = "false"; public static String EMAIL_PROCESS = "emailProcess"; public static String INVOICE_CODE = "invoiceCode"; public static String INVOICE_NUMBER = "invoiceNumber"; }

补充(导包贴图) 在这里插入图片描述 在这里插入图片描述

**全部代码都在这里,我在里面删除了自己好多项目具体自己处理的逻辑,有不对的地方可以指出,我再进行修改。**


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3