mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-11-04 09:01:40 +08:00 
			
		
		
		
	feat(messaging/mail): 新增动态邮箱配置
This commit is contained in:
		@@ -0,0 +1,109 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * <p>
 | 
			
		||||
 * http://www.gnu.org/licenses/lgpl.html
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.continew.starter.messaging.mail.core;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.util.ObjectUtil;
 | 
			
		||||
import cn.hutool.extra.spring.SpringUtil;
 | 
			
		||||
import jakarta.mail.Authenticator;
 | 
			
		||||
import jakarta.mail.PasswordAuthentication;
 | 
			
		||||
import jakarta.mail.Session;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import org.springframework.mail.javamail.JavaMailSender;
 | 
			
		||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
 | 
			
		||||
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 邮件发送器
 | 
			
		||||
 *
 | 
			
		||||
 * @author KAI
 | 
			
		||||
 * @since 1.0.0
 | 
			
		||||
 */
 | 
			
		||||
public class DynamicMailSenderAutoConfiguration extends JavaMailSenderImpl {
 | 
			
		||||
    private static final Logger log = LoggerFactory.getLogger(DynamicMailSenderAutoConfiguration.class);
 | 
			
		||||
 | 
			
		||||
    // 邮件会话属性
 | 
			
		||||
    private final Properties javaMailProperties;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 构造函数,使用给定的邮件会话属性初始化邮件发送器。
 | 
			
		||||
     *
 | 
			
		||||
     * @param javaMailProperties 邮件会话属性
 | 
			
		||||
     */
 | 
			
		||||
    public DynamicMailSenderAutoConfiguration(Properties javaMailProperties) {
 | 
			
		||||
        super(); // 调用父类的构造函数
 | 
			
		||||
        this.javaMailProperties = javaMailProperties;
 | 
			
		||||
 | 
			
		||||
        // 设置用户名和密码
 | 
			
		||||
        setUsername(javaMailProperties.getProperty("mail.smtp.username"));
 | 
			
		||||
        setPassword(javaMailProperties.getProperty("mail.smtp.password"));
 | 
			
		||||
 | 
			
		||||
        // 设置默认编码
 | 
			
		||||
        String defaultEncoding = javaMailProperties.getProperty("mail.default-encoding", "utf-8");
 | 
			
		||||
        setDefaultEncoding(defaultEncoding);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取邮件会话。
 | 
			
		||||
     *
 | 
			
		||||
     * @return 邮件会话
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public Session getSession() {
 | 
			
		||||
        if (ObjectUtil.isNotEmpty(javaMailProperties)) {
 | 
			
		||||
            // 使用提供的身份验证器创建邮件会话
 | 
			
		||||
            log.info("[ContiNew Starter] DynamicMailSenderAutoConfiguration creating session with properties: {}", javaMailProperties);
 | 
			
		||||
            return Session.getInstance(javaMailProperties, new Authenticator() {
 | 
			
		||||
                @Override
 | 
			
		||||
                protected PasswordAuthentication getPasswordAuthentication() {
 | 
			
		||||
                    // 返回用户名和密码认证信息
 | 
			
		||||
                    return new PasswordAuthentication(javaMailProperties
 | 
			
		||||
                        .getProperty("mail.username"), javaMailProperties.getProperty("mail.password"));
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        // 如果没有提供属性,使用父类的会话
 | 
			
		||||
        return super.getSession();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 创建默认的邮件发送器。
 | 
			
		||||
     *
 | 
			
		||||
     * @return 默认的邮件发送器
 | 
			
		||||
     */
 | 
			
		||||
    public static JavaMailSender createDefault() {
 | 
			
		||||
        return SpringUtil.getBean(JavaMailSender.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据邮件配置构建邮件发送器。
 | 
			
		||||
     *
 | 
			
		||||
     * @param mailConfig 邮件配置对象
 | 
			
		||||
     * @return 构建的邮件发送器
 | 
			
		||||
     */
 | 
			
		||||
    public static JavaMailSender build(MailConfig mailConfig) {
 | 
			
		||||
        if (mailConfig != null) {
 | 
			
		||||
            Properties properties = mailConfig.toJavaMailProperties();
 | 
			
		||||
            log.info("[ContiNew Starter] DynamicMailSenderAutoConfiguration build with mailConfig");
 | 
			
		||||
            return new DynamicMailSenderAutoConfiguration(properties);
 | 
			
		||||
        } else {
 | 
			
		||||
            log.error("[ContiNew Starter] Mail configuration is null, using default mail configuration.");
 | 
			
		||||
            return createDefault();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,185 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * <p>
 | 
			
		||||
 * http://www.gnu.org/licenses/lgpl.html
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.continew.starter.messaging.mail.core;
 | 
			
		||||
 | 
			
		||||
import top.continew.starter.core.util.validate.ValidationUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 邮件配置类
 | 
			
		||||
 *
 | 
			
		||||
 * @author KAI
 | 
			
		||||
 * @since 1.0.0
 | 
			
		||||
 */
 | 
			
		||||
public class MailConfig {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 邮件发送协议 (例如: smtp, smtps)
 | 
			
		||||
     */
 | 
			
		||||
    private String mailProtocol = "smtp";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SMTP 服务器地址
 | 
			
		||||
     */
 | 
			
		||||
    private String mailHost;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SMTP 服务器端口
 | 
			
		||||
     */
 | 
			
		||||
    private int mailPort;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SMTP 用户名
 | 
			
		||||
     */
 | 
			
		||||
    private String mailUsername;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SMTP 授权码
 | 
			
		||||
     */
 | 
			
		||||
    private String mailPassword;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 发件人邮箱地址
 | 
			
		||||
     */
 | 
			
		||||
    private String mailFrom;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否启用 SSL 连接
 | 
			
		||||
     */
 | 
			
		||||
    private boolean sslEnabled = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SSL 端口
 | 
			
		||||
     */
 | 
			
		||||
    private int sslPort;
 | 
			
		||||
 | 
			
		||||
    public String getMailProtocol() {
 | 
			
		||||
        return mailProtocol;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMailProtocol(String mailProtocol) {
 | 
			
		||||
        this.mailProtocol = mailProtocol;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getMailHost() {
 | 
			
		||||
        return mailHost;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMailHost(String mailHost) {
 | 
			
		||||
        this.mailHost = mailHost;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getMailPort() {
 | 
			
		||||
        return mailPort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMailPort(int mailPort) {
 | 
			
		||||
        this.mailPort = mailPort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getMailUsername() {
 | 
			
		||||
        return mailUsername;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMailUsername(String mailUsername) {
 | 
			
		||||
        this.mailUsername = mailUsername;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getMailPassword() {
 | 
			
		||||
        return mailPassword;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMailPassword(String mailPassword) {
 | 
			
		||||
        this.mailPassword = mailPassword;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getMailFrom() {
 | 
			
		||||
        return mailFrom;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMailFrom(String mailFrom) {
 | 
			
		||||
        this.mailFrom = mailFrom;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isSslEnabled() {
 | 
			
		||||
        return sslEnabled;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSslEnabled(boolean sslEnabled) {
 | 
			
		||||
        this.sslEnabled = sslEnabled;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getSslPort() {
 | 
			
		||||
        return sslPort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSslPort(int sslPort) {
 | 
			
		||||
        this.sslPort = sslPort;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 将当前配置转换为 JavaMail 的 Properties 对象
 | 
			
		||||
     *
 | 
			
		||||
     * @return 配置好的 Properties 对象
 | 
			
		||||
     */
 | 
			
		||||
    public Properties toJavaMailProperties() {
 | 
			
		||||
        Properties javaMailProperties = new Properties();
 | 
			
		||||
 | 
			
		||||
        ValidationUtils.throwIf(!this.mailProtocol.equals("smtp"), "不支持的邮件发送协议: " + this.mailProtocol);
 | 
			
		||||
        // 设置邮件发送协议
 | 
			
		||||
        javaMailProperties.put("mail.transport.protocol", this.mailProtocol.toLowerCase());
 | 
			
		||||
 | 
			
		||||
        // 设置 SMTP 服务器地址
 | 
			
		||||
        ValidationUtils.throwIfBlank(this.mailHost, "SMTP服务器地址不能为空");
 | 
			
		||||
        javaMailProperties.put("mail.smtp.host", this.mailHost);
 | 
			
		||||
 | 
			
		||||
        // 设置 SMTP 服务器端口
 | 
			
		||||
        ValidationUtils.throwIfNull(this.mailPort, "SMTP服务端口不能为空");
 | 
			
		||||
        javaMailProperties.put("mail.smtp.port", this.mailPort);
 | 
			
		||||
 | 
			
		||||
        // 设置 SMTP 用户名
 | 
			
		||||
        ValidationUtils.throwIfBlank(this.mailUsername, "SMTP用户名不能为空");
 | 
			
		||||
        javaMailProperties.put("mail.smtp.user", this.mailUsername);
 | 
			
		||||
 | 
			
		||||
        // 设置 SMTP 授权码
 | 
			
		||||
        ValidationUtils.throwIfBlank(this.mailPassword, "SMTP授权码不能为空");
 | 
			
		||||
        javaMailProperties.put("mail.smtp.password", this.mailPassword);
 | 
			
		||||
 | 
			
		||||
        // 启用 SMTP 认证
 | 
			
		||||
        javaMailProperties.put("mail.smtp.auth", "true");
 | 
			
		||||
 | 
			
		||||
        // 设置 SSL 连接
 | 
			
		||||
        javaMailProperties.put("mail.smtp.ssl.enable", this.sslEnabled);
 | 
			
		||||
 | 
			
		||||
        // 设置默认发件人地址
 | 
			
		||||
        ValidationUtils.throwIfBlank(this.mailFrom, "默认发件人地址不能为空");
 | 
			
		||||
        javaMailProperties.put("mail.from", this.mailFrom);
 | 
			
		||||
 | 
			
		||||
        // 设置默认编码为 UTF-8
 | 
			
		||||
        javaMailProperties.put("mail.defaultEncoding", "utf-8");
 | 
			
		||||
 | 
			
		||||
        // 如果启用 SSL,设置 SSL Socket 工厂和端口
 | 
			
		||||
        if (sslEnabled) {
 | 
			
		||||
            ValidationUtils.throwIfNull(this.sslPort, "SSL端口不能为空");
 | 
			
		||||
            javaMailProperties.put("mail.smtp.socketFactory.port", this.sslPort);
 | 
			
		||||
            javaMailProperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return javaMailProperties;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -18,14 +18,17 @@ package top.continew.starter.messaging.mail.util;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.collection.CollUtil;
 | 
			
		||||
import cn.hutool.core.lang.Assert;
 | 
			
		||||
import cn.hutool.core.util.ArrayUtil;
 | 
			
		||||
import cn.hutool.core.text.CharSequenceUtil;
 | 
			
		||||
import cn.hutool.core.util.ArrayUtil;
 | 
			
		||||
import cn.hutool.extra.spring.SpringUtil;
 | 
			
		||||
import jakarta.mail.MessagingException;
 | 
			
		||||
import jakarta.mail.internet.MimeMessage;
 | 
			
		||||
import org.springframework.mail.javamail.JavaMailSender;
 | 
			
		||||
import org.springframework.mail.javamail.MimeMessageHelper;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
import top.continew.starter.core.constant.StringConstants;
 | 
			
		||||
import top.continew.starter.messaging.mail.core.MailConfig;
 | 
			
		||||
import top.continew.starter.messaging.mail.core.DynamicMailSenderAutoConfiguration;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
@@ -39,9 +42,14 @@ import java.util.List;
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 1.0.0
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MailUtils {
 | 
			
		||||
 | 
			
		||||
    private static final JavaMailSender MAIL_SENDER = SpringUtil.getBean(JavaMailSender.class);
 | 
			
		||||
    private static MailConfig mailConfig; // 邮件配置
 | 
			
		||||
 | 
			
		||||
    public static void setMailConfig(MailConfig mailConfig) {
 | 
			
		||||
        MailUtils.mailConfig = mailConfig;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private MailUtils() {
 | 
			
		||||
    }
 | 
			
		||||
@@ -157,11 +165,20 @@ public class MailUtils {
 | 
			
		||||
                            boolean isHtml,
 | 
			
		||||
                            File... files) throws MessagingException {
 | 
			
		||||
        Assert.isFalse(CollUtil.isEmpty(tos), "请至少指定一名收件人");
 | 
			
		||||
        MimeMessage mimeMessage = MAIL_SENDER.createMimeMessage();
 | 
			
		||||
        JavaMailSender mailSender = DynamicMailSenderAutoConfiguration.build(mailConfig);
 | 
			
		||||
        String form;
 | 
			
		||||
        if (mailConfig != null && StringUtils.hasText(mailConfig.getMailFrom())) {
 | 
			
		||||
            form = mailConfig.getMailFrom();
 | 
			
		||||
        } else {
 | 
			
		||||
            form = SpringUtil.getProperty("spring.mail.username");
 | 
			
		||||
        }
 | 
			
		||||
        MimeMessage mimeMessage = mailSender.createMimeMessage();
 | 
			
		||||
        // 创建邮件发送器
 | 
			
		||||
        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, StandardCharsets.UTF_8
 | 
			
		||||
            .displayName());
 | 
			
		||||
 | 
			
		||||
        // 设置基本信息
 | 
			
		||||
        messageHelper.setFrom(SpringUtil.getProperty("spring.mail.username"));
 | 
			
		||||
        messageHelper.setFrom(form);
 | 
			
		||||
        messageHelper.setSubject(subject);
 | 
			
		||||
        messageHelper.setText(content, isHtml);
 | 
			
		||||
        // 设置收信人
 | 
			
		||||
@@ -182,7 +199,7 @@ public class MailUtils {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // 发送邮件
 | 
			
		||||
        MAIL_SENDER.send(mimeMessage);
 | 
			
		||||
        mailSender.send(mimeMessage);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user