【Java】JavaMail使用网易企业邮箱发邮件
邮件发送器
/** * 邮件发送器 * * @author Zebe */ public class MailSender implements Runnable { /** * 收件人 */ private String to; /** * 收件人名称 */ private String toName; /** * 主题 */ private String subject; /** * 内容 */ private String content; /** * 附件列表 */ private List<String> attachFileList; /** * 构造器 * @param to 收件人 * @param subject 主题 * @param content 内容 */ public MailSender(String to,String toName, String subject, String content) { this.to = to; this.toName = toName; this.subject = subject; this.content = content; } /** * 构造器 * @param to 收件人 * @param subject 主题 * @param content 内容 * @param attachFileList 附件列表 */ public MailSender(String to, String toName,String subject, String content, List<String> attachFileList) { this(to, toName, subject, content); this.attachFileList = attachFileList; } @Override public void run() { new SendEmailUtil(to,toName, subject, content, attachFileList).send(); } }
邮件发送线程池
/** * 邮件发送线程池 * * @author Zebe */ public class MailSenderPool { /** * 邮件发送器线程数量 */ private static int SENDER_TOTAL = 10; /** * 线程工厂(生产环境中建议使用带命名参数的线程工厂) */ private static ThreadFactory threadFactory = Executors.defaultThreadFactory(); /** * 线程池执行器(采用了Spring提供的CustomizableThreadFactory,如果不需要请使用默认线程工厂) */ private static ExecutorService executor = new ThreadPoolExecutor(SENDER_TOTAL, 200, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy()); /** * 内部静态实例 */ private static class Inner { private static MailSenderPool instance = new MailSenderPool(); } /** * 获取实例 * * @return 返回邮件发送线程池实例 */ public static MailSenderPool getInstance() { return Inner.instance; } /** * 通过线程发送 * * @param sender 邮件发送器 * @return 返回自身 */ public MailSenderPool sendByThread(MailSender sender) { executor.execute(sender); return getInstance(); } /** * 关闭线程池 */ public void shutDown() { executor.shutdown(); } }
邮件发送工具类
/** * 邮件发送工具类。 * 以下邮件中的配置参数,请在实际环境中,根据需要采取合适的配置方式。 * 发送邮件依赖 com.sun.mail(1.6.1) 包、javax.mail(1.5.0-b01) 包。 * 如果使用 Idea 运行,请将这两个包(可以直接到Maven目录下面去找)添加到项目的 Libraries 里面(快捷键:Ctrl + Alt + Shift + S) * * @author Zebe */ public class SendEmailUtil { /** * 发件人别名(可以为空) */ private final static String fromAliasName = "****"; /** * 登录用户名 */ private String ACCOUNT; /** * 登录密码 */ private String PASSWORD; /** * 邮件服务器地址 */ //QQ企业邮箱:smtp.exmail.qq.com //网易企业邮箱:smtphz.qiye.163.com private String HOST; /** * 发信端口 */ //QQ企业邮箱:465 //网易企业邮箱:994 private String PORT; /** * 发信协议 */ private final static String PROTOCOL = "ssl"; /** * 收件人 */ private String to; /** * 收件人名称 */ private String toName; /** * 主题 */ private String subject; /** * 内容 */ private String content; /** * 附件列表(可以为空) */ private List<String> attachFileList; /** * 构造器 * * @param attachFileList 附件列表 */ public SendEmailUtil(MailTemplate mailTemplate, List<String> attachFileList) { this.to = mailTemplate.getTo(); this.toName = mailTemplate.getToName(); this.subject = mailTemplate.getSubject(); this.content = mailTemplate.getContent(); this.attachFileList = attachFileList; this.ACCOUNT = mailTemplate.getAccount(); this.PASSWORD = mailTemplate.getPassword(); switch (mailTemplate.getSendType()) { case "qq": this.HOST = "smtp.exmail.qq.com"; this.PORT = "465"; break; case "163": this.HOST = "smtp.ym.163.com"; this.PORT = "994"; break; } } /** * 认证信息 */ static class MyAuthenticator extends Authenticator { /** * 用户名 */ String username = null; /** * 密码 */ String password = null; /** * 构造器 * * @param username 用户名 * @param password 密码 */ public MyAuthenticator(String username, String password) { this.username = username; this.password = password; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } } /** * 发送邮件 */ public boolean send() { // 设置邮件属性 Properties prop = new Properties(); prop.setProperty("mail.transport.protocol", PROTOCOL); prop.setProperty("mail.smtp.host", HOST); prop.setProperty("mail.smtp.port", PORT); prop.setProperty("mail.smtp.auth", "true"); MailSSLSocketFactory sslSocketFactory = null; try { sslSocketFactory = new MailSSLSocketFactory(); sslSocketFactory.setTrustAllHosts(true); } catch (GeneralSecurityException e1) { e1.printStackTrace(); } if (sslSocketFactory == null) { System.err.println("开启 MailSSLSocketFactory 失败"); } else { prop.put("mail.smtp.ssl.enable", "true"); prop.put("mail.smtp.ssl.socketFactory", sslSocketFactory); // 创建邮件会话(注意,如果要在一个进程中切换多个邮箱账号发信,应该用 Session.getInstance) Session session = Session.getDefaultInstance(prop, new MyAuthenticator(ACCOUNT, PASSWORD)); // 开启调试模式(生产环境中请不要开启此项) session.setDebug(true); try { MimeMessage mimeMessage = new MimeMessage(session); // 设置发件人别名(如果未设置别名就默认为发件人邮箱) mimeMessage.setFrom(new InternetAddress(ACCOUNT, fromAliasName)); // 设置主题和收件人、发信时间等信息 mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to, toName)); mimeMessage.setSubject(subject); mimeMessage.setSentDate(new Date()); //图片 MimeBodyPart img = new MimeBodyPart(); DataHandler dh = new DataHandler(new FileDataSource("src/main/resources/2.jpg"));//图片路径 img.setDataHandler(dh); img.setContentID("img"); //正文 MimeBodyPart text = new MimeBodyPart(); text.setContent("这里正文内容 for img<img src='cid:img'><br/>", "text/html;charset=utf-8"); //注意编码问题 //描述数据关系 MimeMultipart mm = new MimeMultipart(); mm.addBodyPart(text); mm.addBodyPart(img); mm.setSubType("related"); //图片-文本--复合--转普通节点 MimeBodyPart tex_image_tPart=new MimeBodyPart(); tex_image_tPart.setContent(mm); // 如果有附件信息,则添加附件 if (!attachFileList.isEmpty()) { Multipart multipart = new MimeMultipart(); MimeBodyPart body = new MimeBodyPart(); body.setContent(content, "text/html; charset=UTF-8"); multipart.addBodyPart(body); // 添加所有附件(添加时判断文件是否存在) for (String filePath : attachFileList) { if (Files.exists(Paths.get(filePath))) { MimeBodyPart tempBodyPart = new MimeBodyPart(); tempBodyPart.attachFile(filePath); multipart.addBodyPart(tempBodyPart); } } mimeMessage.setContent(multipart); } else { // Multipart multipart = new MimeMultipart(); // MimeBodyPart body = new MimeBodyPart(); // body.setContent(mm, "text/html; charset=UTF-8"); // multipart.addBodyPart(body); MimeMultipart mimeMultipart1=new MimeMultipart(); mimeMultipart1.addBodyPart(tex_image_tPart); mimeMultipart1.setSubType("mixd");//混合关系 mimeMessage.setContent(mimeMultipart1, "text/html; charset=UTF-8"); //mimeMessage.setText(content); } // 开始发信 mimeMessage.saveChanges(); Transport.send(mimeMessage); return true; } catch (MessagingException | IOException e) { e.printStackTrace(); return false; } } return false; } }
示例
public static void main(String[] args) { try { int num; // 通过线程池发送邮件 MailSenderPool pool = MailSenderPool.getInstance(); for (num=1;num<=73;num++){ // 设置发信参数 final String toName = "我是" + num + "号"; final String to = "test" + num + "@***.com"; String subject = num + " 第一次发送测试邮件标题"; final String content = "<p style='color:red'>这是邮件内容正文。</p>"; // 设置附件路径(注意:res 是项目根目录下的一个文件夹) // final List<String> attachFileList = Arrays.asList("res/1.png", "res/1.pdf"); pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>())); subject = num + " 第二次发送测试邮件标题"; pool.sendByThread(new MailSender(to,toName, subject, content, new ArrayList<>())); } pool.shutDown(); }catch (Exception e){ System.out.println("错误: " + e); } }