package import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.Address; import javax.mail.Authenticator; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestMailSender { private static final Logger log = LoggerFactory.getLogger(MailSender.class); /* 邮箱配置详情 */ private static final String MAIL_SMTP_AUTH = "true"; private static final String MAIL_HOST = ""; private static final String MAIL_TRANSPORT_PROTOCOL = "smtp"; private static final String MAIL_SMTP_PORT = "25"; private static final String MAIL_AUTH_NAME = ""; private static final String MAIL_AUTH_PASSWORD = ""; private static final String MAIL_DISPLAY_SENDNAME = "发件人"; private static final String MAIL_DISPLAY_SENDMAIL = ""; private static final String MAIL_SEND_CHARSET = "UTF-8"; private static final boolean MAIL_IS_DEBUG = true; /* 邮箱逻辑配置 */ private static final int MAIL_FAILED_RESEND_TIMES = 3; // 同步、异步发送邮件失败,尝试发送次数 private static final long MAIL_FAILED_ASYN_RESEND_WAITING_MILLISECONDS = 10000; // 异步多线程发送邮件失败,重试间隔时间 private static final long MAIL_FAILED_SYNC_RESEND_WAITING_MILLISECONDS = 3000; // 同步发送邮件失败,线程等待时间 public static final long MAIL_ASYN_SEND_SPACING_MILLISECONDS = 2000; public static final long MAIL_SYNC_SEND_SPACING_MILLISECONDS = 1000; private static final Message message = initMessage(); // 初始化邮箱配置 private static final Message initMessage() { // 基本配置 Properties props = new Properties(); props.setProperty("mail.smtp.auth", MAIL_SMTP_AUTH); props.setProperty("mail.host", MAIL_HOST); props.setProperty("mail.transport.protocol", MAIL_TRANSPORT_PROTOCOL); props.setProperty("mail.smtp.port", MAIL_SMTP_PORT); Session session = Session.getInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(MAIL_AUTH_NAME, MAIL_AUTH_PASSWORD); } }); session.setDebug(MAIL_IS_DEBUG); Message message = new MimeMessage(session); try { message.setFrom(new InternetAddress(MimeUtility .encodeText(MAIL_DISPLAY_SENDNAME) + "<" + MAIL_DISPLAY_SENDMAIL + ">")); } catch (AddressException e) { log.error("初始化邮箱配置失败", e); throw new RuntimeException(e.getMessage()); } catch (UnsupportedEncodingException e) { log.error("初始化邮箱配置失败", e); throw new RuntimeException(e.getMessage()); } catch (MessagingException e) { log.error("初始化邮箱配置失败", e); throw new RuntimeException(e.getMessage()); } return message; } /** * 异步根据主题和内容发送邮件 * * @param subject 邮件主题 * @param content 邮件内容 * @param beSentMails 接收邮件的邮箱地址,不合法的邮箱会自动过滤,如果没有合法邮箱不会发送任何邮件 */ public static void asynMail(String subject, String content, String... beSentMails) { Thread thread = new MailSenderByContentDetailThread(subject, content, beSentMails); thread.start(); } /** * 异步根据主题和内容发送邮件(带附件) * * @param subject 邮件主题 * @param content 邮件内容 * @param attachmentName 附件文件名 * @param attachmentFile 附件地址 * @param beSentMails 接收邮件的邮箱地址,不合法的邮箱会自动过滤,如果没有合法邮箱不会发送任何邮件 */ public static void asynMultiMail(String subject, String content, String attachmentName, String attachmentFile, String... beSentMails) { Thread thread = new MailSenderByContentDetailThread(subject, content, attachmentName, attachmentFile,beSentMails); thread.start(); } /** * 内部包装,根据主题和内容发送邮件 * * @param subject 邮件主题 * @param content 邮件内容 * @param beSentMails 接收邮件的邮箱地址,不合法的邮箱会自动过滤,如果没有合法邮箱不会发送任何邮件 */ private static final synchronized void sendMail(String subject, String content, String... beSentMails) { // 过滤不合法邮箱 beSentMails = validBeSentMails(beSentMails); // 检验过滤结果 if (ArrayUtils.isEmpty(beSentMails)) { return; } try { message.setSubject(subject); message.setContent(content,"text/html;charset=" + MAIL_SEND_CHARSET ); Address[] addresses = new Address[beSentMails.length]; for (int i = 0; i < beSentMails.length; i++) { addresses[i] = new InternetAddress(beSentMails[i]); } message.setRecipients(Message.RecipientType.TO, addresses); Transport.send(message); } catch (Exception e) { log.error("根据主题和内容发送邮失败", e); throw new RuntimeException("resend" + e.getMessage()); } } /** * 内部包装,根据主题和内容发送邮件(带附件) * * @param subject 邮件主题 * @param content 邮件内容 * @param attachmentName 附件文件名 * @param attachmentFile 附件地址 * @param beSentMails 接收邮件的邮箱地址,不合法的邮箱会自动过滤,如果没有合法邮箱不会发送任何邮件 */ private static final synchronized void sendMultiMail(String subject, String content, String attachmentName, String attachmentFile, String... beSentMails) { // 过滤不合法邮箱 beSentMails = validBeSentMails(beSentMails); // 检验过滤结果 if (ArrayUtils.isEmpty(beSentMails)) { return; } try { //邮件标题 message.setSubject(subject); //message.setContent(content,"text/html;charset=" + MAIL_SEND_CHARSET ); Multipart multipart = new MimeMultipart(); //设置邮件的文本内容 BodyPart contentPart = new MimeBodyPart(); contentPart.setText(content); multipart.addBodyPart(contentPart); //添加附件 BodyPart messageBodyPart= new MimeBodyPart(); DataSource source = new FileDataSource(attachmentFile); //添加附件的内容 messageBodyPart.setDataHandler(new DataHandler(source)); //添加附件的标题 messageBodyPart.setFileName(attachmentName); multipart.addBodyPart(messageBodyPart); //将multipart对象放到message中 message.setContent(multipart); //保存邮件 message.saveChanges(); Address[] addresses = new Address[beSentMails.length]; for (int i = 0; i < beSentMails.length; i++) { addresses[i] = new InternetAddress(beSentMails[i]); } message.setRecipients(Message.RecipientType.TO, addresses); Transport.send(message); } catch (Exception e) { log.error("根据主题和内容发送邮失败", e); throw new RuntimeException("resend" + e.getMessage()); } } // 返回所有合法的邮箱,都不合法则返回空 private static String[] validBeSentMails(String... beSentMails) { // 没有任何接收邮箱 if (ArrayUtils.isEmpty(beSentMails)) { return null; } // 验证邮箱格式合法性 Pattern pattern = Pattern.compile("^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"); List<String> finalBeSentMails = new ArrayList<String>(); for (String tmp : beSentMails) { if (StringUtils.isEmpty(tmp)) { continue; } Matcher matcher = pattern.matcher(tmp); if (matcher.matches()) { finalBeSentMails.add(tmp); } } // 只给合法的地址发送邮件 if (finalBeSentMails.size() != beSentMails.length) { if (finalBeSentMails.size() == 0) { return null; } return finalBeSentMails.toArray(new String[finalBeSentMails.size()]); } // 所有邮箱均合法 return beSentMails; } // 根据详情发送邮件线程类 static final class MailSenderByContentDetailThread extends Thread { private String subject; private String content; private String[] beSentMails; private String attachmentName;//附件文件名 private String attachmentFile;//附件文件位置 MailSenderByContentDetailThread(String subject, String content, String[] beSentMails) { this.subject = subject; this.content = content; this.beSentMails = beSentMails; this.attachmentName = null; this.attachmentFile = null; } MailSenderByContentDetailThread(String subject, String content, String attachmentName, String attachmentFile, String[] beSentMails) { this.subject = subject; this.content = content; this.beSentMails = beSentMails; this.attachmentName = attachmentName; this.attachmentFile = attachmentFile; } @Override public void run() { int sendTimes = 0; int i = 0; // 发送次数在允许尝试范围内 do { try { // 发送邮件 for (; i < beSentMails.length; i++) { if(StringUtils.isNotBlank(attachmentName) && StringUtils.isNotBlank(attachmentFile)){ TestMailSender.sendMultiMail(subject, content, attachmentName, attachmentFile, beSentMails[i]); }else{ TestMailSender.sendMail(subject, content, beSentMails[i]); } if (i < beSentMails.length - 1) { Thread.sleep(MAIL_ASYN_SEND_SPACING_MILLISECONDS); } } break; } catch(Exception e) { // 不是邮件发送的异常,直接输出错误信息并跳出 if (!e.getMessage().startsWith("resend")) { log.error("邮件发送失败", e); break; } // 发送次数已到达允许尝试范围,记录错误信息 if (sendTimes == MAIL_FAILED_RESEND_TIMES) { log.error("邮件发送失败,错误原因:{}" , e.getMessage().substring(6, e.getMessage().length() - 1)); log.error("发送主题为:{}" ,subject); log.error("发送内容为:{}" , content); log.error("接收邮箱有:{}" , Arrays.toString(beSentMails)); log.error("为<{}>发送邮件时出错,后续邮件均未发送。",beSentMails[i]); break; } // 线程休眠后重试 try { Thread.sleep(MAIL_FAILED_ASYN_RESEND_WAITING_MILLISECONDS); } catch (InterruptedException e1) { log.error("线程休眠后重试失败", e1); } } } while (sendTimes++ < MAIL_FAILED_RESEND_TIMES); } } }
相关推荐
JavaMail 是一个开源的 Java API,它允许开发者在 Java 应用程序中发送和接收电子邮件。这个API提供了全面的电子邮件处理功能,包括SMTP、POP3和IMAP协议的支持。在JavaMail的使用过程中,通常会涉及到两个核心的JAR...
在本文中,我们将深入探讨如何使用JavaMail API来发送带有附件的电子邮件。 首先,我们需要理解JavaMail的基本组件。`javax.mail.Session`是JavaMail的核心,用于管理邮件会话和配置邮件服务器信息。`Message`对象...
在Java编程中,发送带有附件的电子邮件是一项常见的任务,尤其在自动化报告、系统通知或数据共享等场景下。本文将详细讲解如何使用Java发送带有附件的邮件,主要涉及以下知识点: 1. JavaMail API:JavaMail是Java...
在描述中提到的"email",通常是指这个压缩包包含的JavaMail相关jar文件,可能包括了`javax.mail.jar`、`javax.mail-api.jar`、`activation.jar`等。`activation.jar`是JavaBeans Activation Framework (JAF) 的一...
4. 设置附件:如果需要发送附件,可以通过EmailMessage的addAttachment方法添加。 5. 发送邮件:使用EmailMessage的send方法将邮件发送出去。 接收邮件部分,主要涉及到查询和处理邮箱中的邮件: 1. 获取Folder对象...
本教程将深入探讨如何使用Java发送带有附件、支持多接收者且解决乱码问题的电子邮件。 首先,我们需要导入JavaMail API,这是一个用于处理电子邮件的开放源代码库。在Java项目中,可以通过以下Maven依赖引入: ```...
Java发送邮件是软件开发...在实际项目中,可能还需要考虑错误处理、日志记录、异步发送等复杂情况。对于更复杂的邮件服务,可以使用开源库如JavaMailSenderImpl(Spring框架)进行封装,以简化代码并提供更强大的功能。
此外,如果你需要发送大量邮件,考虑使用线程池或者异步处理以提高效率。 对于提供的文档"java实现邮件自动发送的功能例子.doc",它应该详细阐述了上述步骤,包括代码示例和可能遇到的问题。通过阅读该文档,你将...
此外,如果你的应用需要大量发送邮件,还应考虑使用线程池或异步处理来提高效率。 总之,`TestEmail.java`代码应该是一个简单的Java程序,演示了如何使用JavaMail API向指定收件人发送邮件。确保正确配置邮件服务器...
为了发送带有附件的邮件,我们可以使用 `Multipart` 和 `BodyPart` 类: ```java Multipart multipart = new MimeMultipart(); BodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText("邮件正文...
1. **JavaMail API**: 这是Java发送邮件的基础,包括`javax.mail`和`javax.mail.internet`两个包。你需要导入这些包来使用相关的类和方法。 2. **Session对象**: 这是JavaMail的核心,用于配置邮件服务器的连接参数...
Struts2是一个非常流行的Java Web框架,用于构建和维护可扩展且易于管理的企业级应用程序。在Struts2中,发送邮件是一项常见的...此外,考虑到并发性和性能,可能还需要对邮件发送进行适当的异步处理和错误重试机制。
在Java中发送邮件主要涉及到 javax.mail 和 javax.mail.internet 这两个包中的类。 以下是一个简单的JavaMail发送邮件的步骤和相关知识点: 1. **导入必要的库**:首先,你需要在项目中引入JavaMail相关的jar包。...
如果你需要发送带有附件的邮件,可以使用MIME类型处理。例如,如果附件是`incident_email.mp4`,可以这样操作: ```java MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setText("邮件正文...
- `javax.mail.Message`用于创建邮件内容,包括主题、正文、附件等。可以设置各种属性,如发件人、收件人、抄送人、密送人等。 6. **Transport类**: - `javax.mail.Transport`负责实际的邮件发送,调用`...
它包括了`javax.mail`和`javax.mail.internet`两个主要包,提供了一系列的类和接口,如`Session`、`Message`、`MimeMessage`等。 3. **Session对象**:这是JavaMail API的入口点,用于设置SMTP服务器信息、认证信息...
下面是一个简单的JavaMail示例,演示了如何发送带有抄送和附件的邮件: ```java Properties props = new Properties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); ...
在实际项目中,你可能还需要考虑使用异步发送、错误重试、日志记录以及更复杂的邮件格式(如嵌入式图像、CSS样式等)。JavaMail提供了一套完整的API来应对这些需求,使其成为Java开发中处理邮件任务的强大工具。
5. **添加附件**:如果需要发送带有附件的邮件,可以使用`MimeBodyPart`和`MimeMultipart`类。`MimeBodyPart`用于创建单个部分,如文本或附件,`MimeMultipart`则用于组合多个部分。 6. **发送邮件**:最后,使用`...
JavaMail API提供了`javax.mail`和`javax.mail.internet`这两个主要包,包含了创建、发送和接收邮件所需的所有类。发送电子邮件的基本步骤如下: 1. **配置属性**:设置邮件服务器的相关参数,如SMTP服务器地址、...