Java: Jdk17 异步或同步或并行发邮件

项目结构:

04f81a6ea3a654831623d2630e66a1c9

所需要的包:

<dependencies>
    <!-- JavaMail API -->
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
   <groupId>javax.activation</groupId>
   <artifactId>activation</artifactId>
   <version>1.1.1</version>
</dependency>
    <!-- Jackson JSON库 -->
  <!-- 已有的jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.13.0</version> <!-- 版本号需统一 -->
    </dependency>
    
    <!-- 添加jackson-annotations依赖 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.13.0</version> <!-- 与databind版本一致 -->
    </dependency>

<!-- 添加jackson-core依赖(databind也依赖它,保险起见显式声明) -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.13.0</version> <!-- 与databind版本一致 -->
    </dependency>
    <!-- SLF4J日志框架 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.32</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.32</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

 邮件服务配置: mail-config.json

{
  "smtp": {
    "host": "smtp.qq.com",
    "port": "465",
    "auth": true,
    "sslEnable": true,
    "debug": false
  },
  "sender": {
    "email": "463588883@qq.com",
    "password": "your_auth_code",
    "name": "邮件发送者"
  },
  "threadPool": {
    "corePoolSize": 5,
    "maximumPoolSize": 10,
    "keepAliveTime": 60,
    "unit": "SECONDS",
    "queueCapacity": 100
  },
  "retry": {
    "maxRetries": 3,
    "retryDelay": 1000
  }
}

  

 

/**
 * encoding: utf-8
 * 版权所有 2025 ©涂聚文有限公司 ®
 * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
 * 描述:
 * Author    : geovindu,Geovin Du 涂聚文.
 * IDE       : IntelliJ IDEA 2024.3.6 Java 17
 * # database  : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
 * # OS        : window10
 * Datetime  : 2025 - 2025/10/27 - 21:07
 * User      : geovindu
 * Product   : IntelliJ IDEA
 * Project   : swingdemo
 * File      : MailConfig.java
 * explain   : 学习  类
 **/
 
package com.example.mail.config;
 
import com.fasterxml.jackson.databind.ObjectMapper;
 
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
 
/**
 * 邮件配置类
 */
public class MailConfig {
    private SmtpConfig smtp;
    private SenderConfig sender;
    private ThreadPoolConfig threadPool;
    private RetryConfig retry;
 
    // 单例实例
    private static volatile MailConfig instance;
 
    private MailConfig() {
        // 私有构造方法
    }
 
    /**
     * 获取单例实例
     * @return MailConfig实例
     */
    public static MailConfig getInstance() {
        if (instance == null) {
            synchronized (MailConfig.class) {
                if (instance == null) {
                    instance = loadConfig();
                }
            }
        }
        return instance;
    }
 
    /**
     * 从配置文件加载配置
     * @return 加载的MailConfig对象
     */
    private static MailConfig loadConfig() {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            InputStream inputStream = MailConfig.class.getClassLoader().getResourceAsStream("mail-config.json");
            if (inputStream == null) {
                throw new RuntimeException("找不到邮件配置文件 mail-config.json");
            }
            return objectMapper.readValue(inputStream, MailConfig.class);
        } catch (Exception e) {
            throw new RuntimeException("加载邮件配置文件失败", e);
        }
    }
 
    // Getters
    public SmtpConfig getSmtp() {
        return smtp;
    }
 
    public SenderConfig getSender() {
        return sender;
    }
 
    public ThreadPoolConfig getThreadPool() {
        return threadPool;
    }
 
    public RetryConfig getRetry() {
        return retry;
    }
 
    /**
     * SMTP配置
     */
    public static class SmtpConfig {
        private String host;
        private String port;
        private boolean auth;
        private boolean sslEnable;
        private boolean debug;
 
        // Getters
        public String getHost() {
            return host;
        }
 
        public String getPort() {
            return port;
        }
 
        public boolean isAuth() {
            return auth;
        }
 
        public boolean isSslEnable() {
            return sslEnable;
        }
 
        public boolean isDebug() {
            return debug;
        }
    }
 
    /**
     * 发送者配置
     */
    public static class SenderConfig {
        private String email;
        private String password;
        private String name;
 
        // Getters
        public String getEmail() {
            return email;
        }
 
        public String getPassword() {
            return password;
        }
 
        public String getName() {
            return name;
        }
    }
 
    /**
     * 线程池配置
     */
    public static class ThreadPoolConfig {
        private int corePoolSize;
        private int maximumPoolSize;
        private long keepAliveTime;
        private String unit;
        private int queueCapacity;
 
        // Getters
        public int getCorePoolSize() {
            return corePoolSize;
        }
 
        public int getMaximumPoolSize() {
            return maximumPoolSize;
        }
 
        public long getKeepAliveTime() {
            return keepAliveTime;
        }
 
        public TimeUnit getUnit() {
            return TimeUnit.valueOf(unit);
        }
 
        public int getQueueCapacity() {
            return queueCapacity;
        }
    }
 
    /**
     * 重试配置
     */
    public static class RetryConfig {
        private int maxRetries;
        private long retryDelay;
 
        // Getters
        public int getMaxRetries() {
            return maxRetries;
        }
 
        public long getRetryDelay() {
            return retryDelay;
        }
    }
}

  

/**
 * encoding: utf-8
 * 版权所有 2025 ©涂聚文有限公司 ®
 * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
 * 描述:
 * Author    : geovindu,Geovin Du 涂聚文.
 * IDE       : IntelliJ IDEA 2024.3.6 Java 17
 * # database  : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
 * # OS        : window10
 * Datetime  : 2025 - 2025/10/27 - 21:16
 * User      : geovindu
 * Product   : IntelliJ IDEA
 * Project   : swingdemo
 * File      : MailCallback.java
 * explain   : 学习  类
 **/
 
package com.example.mail.core;
 
/**
 * 邮件发送回调接口
 */
public interface MailCallback {
 
    /**
     * 邮件发送成功回调
     * @param message 发送的邮件消息
     * @param duration 发送耗时(毫秒)
     */
    void onSuccess(MailMessage message, long duration);
 
    /**
     * 邮件发送失败回调
     * @param message 发送的邮件消息
     * @param throwable 失败原因
     */
    void onFailure(MailMessage message, Throwable throwable);
}
 
 
 
/**
 * encoding: utf-8
 * 版权所有 2025 ©涂聚文有限公司 ®
 * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
 * 描述:
 * Author    : geovindu,Geovin Du 涂聚文.
 * IDE       : IntelliJ IDEA 2024.3.6 Java 17
 * # database  : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
 * # OS        : window10
 * Datetime  : 2025 - 2025/10/27 - 21:17
 * User      : geovindu
 * Product   : IntelliJ IDEA
 * Project   : swingdemo
 * File      : MailMessage.java
 * explain   : 学习  类
 **/
 
package com.example.mail.core;
 
import java.io.File;
 
/**
 * 邮件消息类,封装邮件内容
 */
public class MailMessage {
    private String[] to;
    private String[] cc;
    private String[] bcc;
    private String subject;
    private String content;
    private boolean html;
    private File[] attachments;
 
    // 私有构造方法,通过Builder创建
    private MailMessage(Builder builder) {
        this.to = builder.to;
        this.cc = builder.cc;
        this.bcc = builder.bcc;
        this.subject = builder.subject;
        this.content = builder.content;
        this.html = builder.html;
        this.attachments = builder.attachments;
    }
 
    // Getters
    public String[] getTo() {
        return to;
    }
 
    public String[] getCc() {
        return cc;
    }
 
    public String[] getBcc() {
        return bcc;
    }
 
    public String getSubject() {
        return subject;
    }
 
    public String getContent() {
        return content;
    }
 
    public boolean isHtml() {
        return html;
    }
 
    public File[] getAttachments() {
        return attachments;
    }
 
    /**
     * 邮件消息构建器
     */
    public static class Builder {
        private String[] to;
        private String[] cc;
        private String[] bcc;
        private String subject;
        private String content;
        private boolean html = false;
        private File[] attachments;
 
        /**
         * 设置收件人
         * @param to 收件人邮箱数组
         * @return Builder
         */
        public Builder to(String... to) {
            this.to = to;
            return this;
        }
 
        /**
         * 设置抄送
         * @param cc 抄送邮箱数组
         * @return Builder
         */
        public Builder cc(String... cc) {
            this.cc = cc;
            return this;
        }
 
        /**
         * 设置密送
         * @param bcc 密送邮箱数组
         * @return Builder
         */
        public Builder bcc(String... bcc) {
            this.bcc = bcc;
            return this;
        }
 
        /**
         * 设置邮件主题
         * @param subject 邮件主题
         * @return Builder
         */
        public Builder subject(String subject) {
            this.subject = subject;
            return this;
        }
 
        /**
         * 设置邮件内容
         * @param content 邮件内容
         * @return Builder
         */
        public Builder content(String content) {
            this.content = content;
            return this;
        }
 
        /**
         * 设置是否为HTML邮件
         * @param html 是否为HTML邮件
         * @return Builder
         */
        public Builder html(boolean html) {
            this.html = html;
            return this;
        }
 
        /**
         * 设置附件
         * @param attachments 附件文件数组
         * @return Builder
         */
        public Builder attachments(File... attachments) {
            this.attachments = attachments;
            return this;
        }
 
        /**
         * 构建MailMessage对象
         * @return MailMessage
         */
        public MailMessage build() {
            if (to == null || to.length == 0) {
                throw new IllegalArgumentException("收件人不能为空");
            }
            if (subject == null || subject.trim().isEmpty()) {
                throw new IllegalArgumentException("邮件主题不能为空");
            }
            if (content == null || content.trim().isEmpty()) {
                throw new IllegalArgumentException("邮件内容不能为空");
            }
            return new MailMessage(this);
        }
    }
}
 
 
 
/**
 * encoding: utf-8
 * 版权所有 2025 ©涂聚文有限公司 ®
 * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
 * 描述:
 * Author    : geovindu,Geovin Du 涂聚文.
 * IDE       : IntelliJ IDEA 2024.3.6 Java 17
 * # database  : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
 * # OS        : window10
 * Datetime  : 2025 - 2025/10/27 - 21:17
 * User      : geovindu
 * Product   : IntelliJ IDEA
 * Project   : swingdemo
 * File      : MailSender.java
 * explain   : 学习  类
 **/
 
package com.example.mail.core;
import com.example.mail.config.MailConfig;
import com.example.mail.exception.MailException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Properties;
import java.util.concurrent.*;
import java.util.stream.Collectors;
 
/**
 * 邮件发送工具类
 */
public class MailSender {
    private static final Logger logger = LoggerFactory.getLogger(MailSender.class);
    private static final MailConfig config = MailConfig.getInstance();
    private static final ExecutorService executorService;
 
    static {
        // 初始化线程池
        MailConfig.ThreadPoolConfig threadPoolConfig = config.getThreadPool();
        executorService = new ThreadPoolExecutor(
                threadPoolConfig.getCorePoolSize(),
                threadPoolConfig.getMaximumPoolSize(),
                threadPoolConfig.getKeepAliveTime(),
                threadPoolConfig.getUnit(),
                new LinkedBlockingQueue<>(threadPoolConfig.getQueueCapacity()),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
 
    /**
     * 同步发送邮件
     * @param message 邮件消息
     * @throws MailException 邮件发送异常
     */
    public static void send(MailMessage message) throws MailException {
        long startTime = System.currentTimeMillis();
        try {
            doSend(message);
            long duration = System.currentTimeMillis() - startTime;
            logger.info("邮件同步发送成功,收件人: {}, 耗时: {}ms",
                    String.join(",",message.getTo()), duration);
        } catch (MessagingException e) {
            logger.error("邮件同步发送失败,收件人: {}",
                    String.join(",", message.getTo()), e);
            throw new MailException("邮件发送失败", e);
        }
    }
 
    /**
     * 异步发送邮件
     * @param message 邮件消息
     * @return Future对象,可用于获取发送结果
     */
    public static Future<Boolean> sendAsync(MailMessage message) {
        return executorService.submit(() -> {
            long startTime = System.currentTimeMillis();
            try {
                doSend(message);
                long duration = System.currentTimeMillis() - startTime;
                logger.info("邮件异步发送成功,收件人: {}, 耗时: {}ms",
                        String.join(",", message.getTo()), duration);
                return true;
            } catch (MessagingException e) {
                logger.error("邮件异步异步发送失败,收件人: {}",
                        String.join(",", message.getTo()), e);
                return false;
            }
        });
    }
 
    /**
     * 异步发送邮件(带回调)
     * @param message 邮件消息
     * @param callback 回调接口
     */
    public static void sendAsync(MailMessage message, MailCallback callback) {
        executorService.submit(() -> {
            long startTime = System.currentTimeMillis();
            try {
                doSend(message);
                long duration = System.currentTimeMillis() - startTime;
                logger.info("邮件异步发送成功,收件人: {}, 耗时: {}ms",
                        String.join(",", message.getTo()), duration);
                if (callback != null) {
                    callback.onSuccess(message, duration);
                }
            } catch (MessagingException e) {
                logger.error("邮件异步发送失败,收件人: {}",
                        String.join(",", message.getTo()), e);
                if (callback != null) {
                    callback.onFailure(message, e);
                }
            }
        });
    }
 
    /**
     * 并行发送多封邮件
     * @param messages 邮件消息列表
     * @return CompletableFuture,可用于获取所有邮件的发送结果
     */
    public static CompletableFuture<java.util.List<Boolean>> sendParallel(java.util.List<MailMessage> messages) {
        java.util.List<CompletableFuture<Boolean>> futures = messages.stream()
                .map(message -> CompletableFuture.supplyAsync(() -> {
                    long startTime = System.currentTimeMillis();
                    try {
                        doSend(message);
                        long duration = System.currentTimeMillis() - startTime;
                        logger.info("邮件并行发送成功,收件人: {}, 耗时: {}ms",
                                String.join(",", message.getTo()), duration);
                        return true;
                    } catch (MessagingException e) {
                        logger.error("邮件并行发送失败,收件人: {}",
                                String.join(",", message.getTo()), e);
                        return false;
                    }
                }, executorService))
                .collect(Collectors.toList());
 
        return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                .thenApply(v -> futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList()));
    }
 
    /**
     * 批量发送邮件(同一内容,多个收件人)
     * @param to 收件人数组
     * @param subject 邮件主题
     * @param content 邮件内容
     * @param attachments 附件数组
     * @return CompletableFuture,可用于获取发送结果
     */
    public static CompletableFuture<Boolean> sendBatch(String[] to, String subject, String content, java.io.File[] attachments) {
        MailMessage message = new MailMessage.Builder()
                .to(to)
                .subject(subject)
                .content(content)
                .attachments(attachments)
                .build();
 
        return CompletableFuture.supplyAsync(() -> {
            long startTime = System.currentTimeMillis();
            try {
                doSend(message);
                long duration = System.currentTimeMillis() - startTime;
                logger.info("邮件批量发送成功,收件人数量: {}, 耗时: {}ms",
                        to.length, duration);
                return true;
            } catch (MessagingException e) {
                logger.error("邮件批量发送失败,收件人数量: {}",
                        to.length, e);
                return false;
            }
        }, executorService);
    }
 
    /**
     * 实际发送邮件的内部方法
     * @param message 邮件消息
     * @throws MessagingException 邮件发送异常
     */
    private static void doSend(MailMessage message) throws MessagingException {
        // 获取SMTP配置
        MailConfig.SmtpConfig smtpConfig = config.getSmtp();
        MailConfig.SenderConfig senderConfig = config.getSender();
        MailConfig.RetryConfig retryConfig = config.getRetry();
 
        // 创建Properties对象
        Properties props = new Properties();
        props.put("mail.smtp.host", smtpConfig.getHost());
        props.put("mail.smtp.port", smtpConfig.getPort());
        props.put("mail.smtp.auth", smtpConfig.isAuth());
        props.put("mail.smtp.ssl.enable", smtpConfig.isSslEnable());
        props.put("mail.debug", smtpConfig.isDebug());
 
        // 创建Session对象
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                        senderConfig.getEmail(),
                        senderConfig.getPassword()
                );
            }
        });
 
        // 创建MimeMessage对象
        MimeMessage mimeMessage = new MimeMessage(session);
        try {
            mimeMessage.setFrom(new InternetAddress(senderConfig.getEmail(), senderConfig.getName()));
        } catch (java.io.UnsupportedEncodingException e) {
            logger.error("设置发件人名称编码失败", e);
            throw new MessagingException("设置发件人失败", e);
        }
 
        // 设置收件人
        if (message.getTo() != null && message.getTo().length > 0) {
            mimeMessage.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(String.join(",", message.getTo())));
        }
 
        // 设置抄送
        if (message.getCc() != null && message.getCc().length > 0) {
            mimeMessage.setRecipients(Message.RecipientType.CC,
                    InternetAddress.parse(String.join(",", message.getCc())));
        }
 
        // 设置密送
        if (message.getBcc() != null && message.getBcc().length > 0) {
            mimeMessage.setRecipients(Message.RecipientType.BCC,
                    InternetAddress.parse(String.join(",", message.getBcc())));
        }
 
        // 设置主题
        mimeMessage.setSubject(message.getSubject(), "UTF-8");
 
        // 创建Multipart对象
        Multipart multipart = new MimeMultipart();
 
        // 创建邮件正文部分
        MimeBodyPart contentPart = new MimeBodyPart();
        contentPart.setContent(message.getContent(),
                message.isHtml() ? "text/html;charset=UTF-8" : "text/plain;charset=UTF-8");
        multipart.addBodyPart(contentPart);
 
        // 添加附件
        if (message.getAttachments() != null && message.getAttachments().length > 0) {
            for (java.io.File attachment : message.getAttachments()) {
                if (attachment.exists() && attachment.isFile()) {
                    MimeBodyPart attachmentPart = new MimeBodyPart();
                    FileDataSource dataSource = new FileDataSource(attachment);
                    attachmentPart.setDataHandler(new DataHandler(dataSource));
                    try {
                        attachmentPart.setFileName(javax.mail.internet.MimeUtility.encodeWord(attachment.getName()));
                    } catch (java.io.UnsupportedEncodingException e) {
                        logger.error("附件文件名编码失败: {}", attachment.getName(), e);
                        throw new MessagingException("设置附件文件名失败", e);
                    }
                    multipart.addBodyPart(attachmentPart);
                } else {
                    logger.warn("附件不存在或不是文件: {}", attachment.getAbsolutePath());
                }
            }
        }
 
        // 设置邮件内容
        mimeMessage.setContent(multipart);
 
        // 发送邮件(带重试机制)
        int retryCount = 0;
        while (true) {
            try {
                Transport.send(mimeMessage);
                break;
            } catch (MessagingException e) {
                if (retryCount < retryConfig.getMaxRetries()) {
                    retryCount++;
                    logger.warn("邮件发送失败,正在重试第 {} 次...", retryCount, e);
                    try {
                        Thread.sleep(retryConfig.getRetryDelay());
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw e;
                    }
                } else {
                    logger.error("邮件发送失败,已达到最大重试次数: {}", retryConfig.getMaxRetries(), e);
                    throw e;
                }
            }
        }
    }
 
    /**
     * 关闭线程池
     */
    public static void shutdown() {
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }
        logger.info("邮件发送线程池已关闭");
    }
}

  

/**
 * encoding: utf-8
 * 版权所有 2025 ©涂聚文有限公司 ®
 * 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
 * 描述:
 * Author    : geovindu,Geovin Du 涂聚文.
 * IDE       : IntelliJ IDEA 2024.3.6 Java 17
 * # database  : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
 * # OS        : window10
 * Datetime  : 2025 - 2025/10/27 - 21:18
 * User      : geovindu
 * Product   : IntelliJ IDEA
 * Project   : swingdemo
 * File      : MailException.java
 * explain   : 学习  类
 **/
 
package com.example.mail.exception;
 
/**
 * 邮件发送异常类
 */
public class MailException extends Exception {
 
    private static final long serialVersionUID = 1L;
 
    /**
     * 错误码
     */
    private String errorCode;
 
    /**
     * 构造方法
     * @param message 错误消息
     */
    public MailException(String message) {
        super(message);
    }
 
    /**
     * 构造方法
     * @param message 错误消息
     * @param cause 异常原因
     */
    public MailException(String message, Throwable cause) {
        super(message, cause);
    }
 
    /**
     * 构造方法
     * @param errorCode 错误码
     * @param message 错误消息
     */
    public MailException(String errorCode, String message) {
        super(message);
        this.errorCode = errorCode;
    }
 
    /**
     * 构造方法
     * @param errorCode 错误码
     * @param message 错误消息
     * @param cause 异常原因
     */
    public MailException(String errorCode, String message, Throwable cause) {
        super(message, cause);
        this.errorCode = errorCode;
    }
 
    // Getter
    public String getErrorCode() {
        return errorCode;
    }
}

  

调用:

 

    /**
     *
     * @param args
     */
    public static void main(String[] args) {

        //sendEmail();
        try {
            // 直接加载配置,验证是否成功
            MailConfig config = MailConfig.getInstance();
            System.out.println("SMTP主机: " + config.getSmtp().getHost());
            System.out.println("发送者邮箱: " + config.getSender().getEmail());
        } catch (Exception e) {
            e.printStackTrace(); // 打印具体异常原因
        }

        try {
            // 测试同步发送邮件
            testSyncSend();

            // 测试异步发送邮件
            testAsyncSend();

            // 测试并行发送邮件
            testParallelSend();

            // 测试批量发送邮件
            testBatchSend();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭线程池
            MailSender.shutdown();
        }


        // 初始化依赖
        //var userRepository = new InMemoryUserRepository();
        //var loginService = new LoginApplicationService(userRepository);

        // 启动应用 - 显示登录窗口
        //javax.swing.SwingUtilities.invokeLater(() -> new LoginWindow(loginService));

        //System.out.println("Hello, World!");
    }

    /**
     * 测试同步发送邮件
     */
    private static void testSyncSend() {
        System.out.println("=== 测试同步发送邮件 ===");
        try {
            MailMessage message = new MailMessage.Builder()
                    .to("geovindu@163.com")
                    .subject("测试同步发送邮件")
                    .content("这是一封测试同步发送的邮件")
                    //.attachments()
                    .html(false)
                    .build();

            MailSender.send(message);
            System.out.println("同步发送邮件成功");
        } catch (MailException e) {
            System.err.println("同步发送邮件失败: " + e.getMessage());
        }
        System.out.println();
    }

    /**
     * 测试异步发送邮件
     */
    private static void testAsyncSend() throws InterruptedException, ExecutionException {
        System.out.println("=== 测试异步发送邮件 ===");
        MailMessage message = new MailMessage.Builder()
                .to("geovindu@163.com")
                .subject("测试异步发送邮件")
                .content("这是一封测试异步发送的邮件")
                //.attachments()
                .html(false)
                .build();

        Future<Boolean> future = MailSender.sendAsync(message);
        System.out.println("异步发送邮件任务已提交");

        // 等待发送完成并获取结果
        Boolean result = future.get();
        System.out.println("异步发送邮件结果: " + (result ? "成功" : "失败"));
        System.out.println();
    }

    /**
     * 测试并行发送邮件
     */
    private static void testParallelSend() throws InterruptedException, ExecutionException {
        System.out.println("=== 测试并行发送邮件 ===");
        MailMessage message1 = new MailMessage.Builder()
                .to("geovindu@163.com")
                .subject("测试并行发送邮件 1")
                .content("这是第一封测试并行发送的邮件")
                .html(false)
                //.attachments()
                .build();

        MailMessage message2 = new MailMessage.Builder()
                .to("413265257@qq.com")
                .subject("测试并行发送邮件 2")
                .content("这是第二封测试并行发送的邮件")
                .html(false)
                //.attachments()
                .build();

        MailMessage message3 = new MailMessage.Builder()
                .to("geovindu@hotmial.com")
                .subject("测试并行发送邮件 3")
                .content("这是第三封测试并行发送的邮件")
                .html(false)
                //.attachments()
                .build();

        List<MailMessage> messages = Arrays.asList(message1, message2, message3);
        System.out.println("并行发送邮件任务已提交");

        // 等待所有邮件发送完成并获取结果
        List<Boolean> results = MailSender.sendParallel(messages).get();
        long successCount = results.stream().filter(Boolean::booleanValue).count();
        System.out.println("并行发送邮件完成,成功: " + successCount + ", 失败: " + (results.size() - successCount));
        System.out.println();
    }

    /**
     * 测试批量发送邮件
     */
    private static void testBatchSend() throws InterruptedException, ExecutionException {
        System.out.println("=== 测试批量发送邮件 ===");
        String[] to = {"413265257@qq.com", "geovindu@hotmial.com", "geovindu@163.com"};
        String subject = "测试批量发送邮件";
        String content = "这是一封测试批量发送的邮件";

        // 可以添加附件测试
        //File[] attachments = {new File("test.txt"), new File("test.pdf")};

        System.out.println("批量发送邮件任务已提交");

        // 等待发送完成并获取结果
        Boolean result = MailSender.sendBatch(to, subject, content, null).get(); // null  attachments
        System.out.println("批量发送邮件结果: " + (result ? "成功" : "失败"));
        System.out.println();
    }

  

 

 

输出:

1f55e548f48b0f48aa1439504169d1fb

 

image

 

import com.example.mail.core.MailSender;
import com.example.mail.core.MailMessage;
import com.example.mail.core.Attachment;
import com.example.mail.exception.MailException;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class MailAttachmentTest {

    // 测试附件路径(resources/attachments下的文件)
    private static final String ATTACHMENT_DIR = "attachments/";
    private static final String TEXT_FILE = ATTACHMENT_DIR + "test.txt";       // 文本附件
    private static final String IMAGE_FILE = ATTACHMENT_DIR + "image.png";     // 图片附件
    private static final String PDF_FILE = ATTACHMENT_DIR + "document.pdf";    // PDF附件

    // 测试收件人(替换为实际测试邮箱)
    private static final String TEST_RECIPIENT = "test@example.com";
    private static final List<String> TEST_RECIPIENTS = Arrays.asList(
        "test1@example.com", "test2@example.com", "test3@example.com"
    );

    public static void main(String[] args) {
        try {
            System.out.println("=== 开始测试同步发送带附件邮件 ===");
            testSyncWithAttachments();

            System.out.println("\n=== 开始测试异步发送带附件邮件 ===");
            testAsyncWithAttachments();

            System.out.println("\n=== 开始测试并行发送带附件邮件 ===");
            testParallelWithAttachments();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试同步发送带附件邮件(单个附件 + 多个附件)
     */
    public static void testSyncWithAttachments() throws MailException {
        // 1. 测试同步发送:单个文本附件
        MailMessage singleAttachmentMsg = MailMessage.builder()
                .to(TEST_RECIPIENT)
                .subject("【同步测试】带单个文本附件的邮件")
                .content("<h1>这是一封同步发送的带单个文本附件的测试邮件</h1>")
                .attachment(getAttachment(TEXT_FILE))  // 添加单个附件
                .build();
        boolean singleSuccess = MailSender.sendEmailSync(singleAttachmentMsg);
        System.out.println("同步发送单个附件结果:" + (singleSuccess ? "成功" : "失败"));

        // 2. 测试同步发送:多个不同类型附件
        MailMessage multiAttachmentsMsg = MailMessage.builder()
                .to(TEST_RECIPIENT)
                .subject("【同步测试】带多个附件的邮件(文本+图片+PDF)")
                .content("<h1>这是一封同步发送的带多个附件的测试邮件</h1>")
                .attachments(Arrays.asList(  // 添加多个附件
                        getAttachment(TEXT_FILE),
                        getAttachment(IMAGE_FILE),
                        getAttachment(PDF_FILE)
                ))
                .build();
        boolean multiSuccess = MailSender.sendEmailSync(multiAttachmentsMsg);
        System.out.println("同步发送多个附件结果:" + (multiSuccess ? "成功" : "失败"));
    }

    /**
     * 测试异步发送带附件邮件(单个附件 + 多个附件)
     */
    public static void testAsyncWithAttachments() throws ExecutionException, InterruptedException {
        // 1. 测试异步发送:单个图片附件
        MailMessage singleImgMsg = MailMessage.builder()
                .to(TEST_RECIPIENT)
                .subject("【异步测试】带单个图片附件的邮件")
                .content("<h1>这是一封异步发送的带单个图片附件的测试邮件</h1>")
                .attachment(getAttachment(IMAGE_FILE))
                .build();
        Future<Boolean> singleImgFuture = MailSender.sendEmailAsync(singleImgMsg);
        boolean singleImgSuccess = singleImgFuture.get();  // 阻塞等待结果
        System.out.println("异步发送单个图片附件结果:" + (singleImgSuccess ? "成功" : "失败"));

        // 2. 测试异步发送:多个附件(文本+PDF)
        MailMessage multiAsyncMsg = MailMessage.builder()
                .to(TEST_RECIPIENT)
                .subject("【异步测试】带文本+PDF附件的邮件")
                .content("<h1>这是一封异步发送的带多个附件的测试邮件</h1>")
                .attachments(Arrays.asList(
                        getAttachment(TEXT_FILE),
                        getAttachment(PDF_FILE)
                ))
                .build();
        Future<Boolean> multiAsyncFuture = MailSender.sendEmailAsync(multiAsyncMsg);
        boolean multiAsyncSuccess = multiAsyncFuture.get();
        System.out.println("异步发送多个附件结果:" + (multiAsyncSuccess ? "成功" : "失败"));
    }

    /**
     * 测试并行发送带附件邮件(批量发送给多个收件人,均带附件)
     */
    public static void testParallelWithAttachments() {
        // 构建多个带附件的邮件消息(每个收件人发送带不同附件的邮件)
        List<MailMessage> messages = new ArrayList<>();
        for (int i = 0; i < TEST_RECIPIENTS.size(); i++) {
            String recipient = TEST_RECIPIENTS.get(i);
            // 轮流使用不同附件(模拟不同邮件带不同附件)
            Attachment attachment = i % 3 == 0 ? getAttachment(TEXT_FILE) :
                                   i % 3 == 1 ? getAttachment(IMAGE_FILE) :
                                   getAttachment(PDF_FILE);

            MailMessage msg = MailMessage.builder()
                    .to(recipient)
                    .subject("【并行测试】第" + (i + 1) + "封带附件的邮件")
                    .content("<h1>这是并行发送的第" + (i + 1) + "封带附件的测试邮件</h1>")
                    .attachment(attachment)
                    .build();
            messages.add(msg);
        }

        // 并行发送并等待结果
        MailSender.sendEmailsParallel(messages)
                .thenAccept(results -> {
                    long successCount = results.stream().filter(Boolean::booleanValue).count();
                    System.out.println("并行发送带附件邮件完成:成功" + successCount + "封,失败" + (results.size() - successCount) + "封");
                })
                .join();  // 阻塞等待所有并行任务完成
    }

    /**
     * 获取附件对象(从resources目录读取文件)
     */
    private static Attachment getAttachment(String resourcePath) {
        try {
            // 读取resources下的附件文件
            File file = new File(MailAttachmentTest.class.getClassLoader().getResource(resourcePath).toURI());
            return new Attachment(file.getName(), file);
        } catch (Exception e) {
            throw new RuntimeException("获取附件失败:" + resourcePath, e);
        }
    }
}

  

 

posted @ 2025-10-27 23:28  ®Geovin Du Dream Park™  阅读(1)  评论(0)    收藏  举报