随手记:Java Mail邮件发送

博客讲述因定时查询芝麻代理余额需求,需用Java Mail写邮件发送功能,公司用阿里企业邮箱,代码采用SMTP协议。本地和测试环境可正常发邮件,但线上环境不行,原因是阿里云封禁25端口,需用安全协议和加密端口,还给出Java Mail邮件发送demo。

进入正题:之所以要写个Java Mail邮件发送的功能。是因为早先有个需求,需要我写个定时任务,使用芝麻代理提供的接口定时去查询余额(数据团队做爬虫会用到芝麻代理),如果余额不足,就发送提醒邮件给专门的负责人。我们公司用的是阿里的企业邮箱,我写的发送件代码使用的是SMTP的协议。
遇到的问题:本地、测试环境都可以正常发送邮件,但一发到线上环境,就无法正常发送邮件。
问题原因:我们公司用的是阿里云服务器,而阿里云封禁了25端口的对内对外的访问。所以就需要使用安全协议,用加密的端口。
在这里插入图片描述
Java Mail邮件发送demo
用到的mail依赖

<!-- email -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

外部配置 mailConfig.properties

#服务器
mailHost=smtp.qiye.aliyun.com
#端口号
mailPort=465
#邮箱账号
mailUsername=your_email@mail.com
#邮箱授权码
mailPassword=your_password(该密码为授权密码,需在对应邮箱中配置,不懂的可以自行百度)
#时间延迟
mailTimeout=1000
#发送人
mailFrom=your_email@mail.com

MailConfig(如果不用mailConfig.properties外部配置,可以直接写Hard Code到此代码中)

package com.zero.testing.util;

import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 读取邮件配置
 *
 * @author Zero
 * @date 2019/3/21
 */
@Component
public class MailConfig {

    private static final String MAIL_CONFIG_PROPERTIES = "mailConfig.properties";

    private static String host;
    private static String port;
    private static String username;
    private static String password;
    private static String from;
    private static String timeout;

    static {
        init();
    }

    /**
     * 初始化
     */
    private static void init() {

        Properties properties = new Properties();
        try (InputStream inputStream = MailConfig.class.getClassLoader().getResourceAsStream(MAIL_CONFIG_PROPERTIES)) {
            properties.load(inputStream);
            host = properties.getProperty("mailHost");
            port = properties.getProperty("mailPort");
            username = properties.getProperty("mailUsername");
            password = properties.getProperty("mailPassword");
            from = properties.getProperty("mailFrom");
            timeout = properties.getProperty("mailTimeout");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getHost() {
        return host;
    }

    public static String getPort() {
        return port;
    }

    public static String getUsername() {
        return username;
    }

    public static String getPassword() {
        return password;
    }

    public static String getFrom() {
        return from;
    }

    public static String getTimeout() {
        return timeout;
    }
}

邮件发送工具

package com.zero.testing.util;

import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;

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;

/**
 * 邮件发送工具
 *
 * @author Zero
 * @date 2019/3/21
 */

@Slf4j
public class MailSender {

    /**
     * MIME邮件对象
     */

    private MimeMessage mimeMsg;

    /**
     * 系统属性
     */
    private Properties props;

    /**
     * Multipart对象,邮件内容、标题、附件等内容
     */
    private Multipart mp;

    /**
     * 邮件会话对象
     */
    private Session session;

    private static final String HOST = MailConfig.getHost();
    private static final String PORT = MailConfig.getPort();
    private static final String USERNAME = MailConfig.getUsername();
    private static final String PASSWORD = MailConfig.getPassword();
    private static final String EMAIL_FROM = MailConfig.getFrom();
    private static final String TIMEOUT = MailConfig.getTimeout();

    private MailSender() {
        initProperties();
        initMimeMessage();
    }

    private void initProperties() {
        //属性设置
        props = new Properties();
        props.put("mail.smtp.host", HOST);
        props.put("mail.smtp.port", PORT);
        props.put("mail.smtp.timeout", TIMEOUT);
        props.put("mail.smtp.auth", true);
        //开启安全协议
        try {
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.ssl.socketFactory", sf);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

    private void initMimeMessage() {
        log.info("获取邮件会话对象");
        try {
            session = Session.getDefaultInstance(props);
        } catch (Exception e) {
            System.err.println("获取邮件会话对象时发生错误!" + e);
            return;
        }
        log.info("创建MIME邮件对象");
        try {
            mimeMsg = new MimeMessage(session);
            log.info("设置发信人");
            mimeMsg.setFrom(new InternetAddress(EMAIL_FROM));
            mp = new MimeMultipart();

        } catch (Exception e) {
            System.err.println("创建MIME邮件对象失败" + e);
        }
    }

    private void setSubject(String mailSubject) {
        log.info("设置邮件主题");
        try {
            mimeMsg.setSubject(mailSubject);
        } catch (Exception e) {
            log.error("设置邮件主题发生错误" + e);
        }
    }

    private void setBody(String mailBody) {
        log.info("设置邮件正文");
        try {
            BodyPart bp = new MimeBodyPart();
            bp.setContent(mailBody, "text/html;charset=utf-8");
            mp.addBodyPart(bp);

        } catch (Exception e) {
            log.error("设置邮件正文发生错误" + e);
        }
    }

    /**
     * 添加邮件附件
     *
     * @param pathname 文件地址
     */
    public void addFileAffix(String pathname) {
        log.info("增加邮件附件:" + pathname);
        try {
            BodyPart bp = new MimeBodyPart();
            FileDataSource fields = new FileDataSource(pathname);
            bp.setDataHandler(new DataHandler(fields));
            bp.setFileName(fields.getName());
            mp.addBodyPart(bp);
        } catch (Exception e) {
            log.error("增加邮件附件" + pathname + "发生错误:" + e);
        }
    }

    private void setTo(String to) {
        log.info("设置邮件发送对象");
        if (to == null) {
            return;
        }
        try {
            mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
        } catch (Exception e) {
            log.error("设置邮件发送对象发生错误" + e);
        }
    }

    private void setCc(String cc) {
        log.info("设置邮件抄送对象");
        if (cc == null) {
            return;
        }
        try {
            mimeMsg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc));
        } catch (Exception e) {
            log.error("设置邮件抄送对象发生错误" + e);
        }
    }

    private void sendOut() {
        try {
            mimeMsg.setContent(mp);
            mimeMsg.saveChanges();

            log.info("正在发送邮件....");

            Transport transport = session.getTransport("smtp");
            transport.connect(HOST, USERNAME, PASSWORD);
            transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());

            log.info("发送邮件成功!");
            transport.close();

        } catch (Exception e) {
            log.error("邮件发送失败!" + e);
        }
    }

    /**
     * 发送提醒邮件
     *
     * @param to       发送目标
     * @param cc       抄送目标
     * @param title    主题
     * @param mailBody 内容
     */
    public static void sendNoticeEmail(String to, String cc, String title, String mailBody) {
        //创建发送邮件对象
        MailSender mailSender = new MailSender();
        mailSender.setTo(to);
        mailSender.setCc(cc);
        mailSender.setSubject(title);
        mailSender.setBody(mailBody);
        mailSender.sendOut();
    }

}

邮件发送Job

package com.zero.testing.job;

import com.zero.testing.util.MailSender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;

/**
 * 邮件发送Job
 *
 * @author Zero
 * @date 2019/2/28
 */

@Slf4j
@Configuration
public class MailSenderJob {

    /**
     * 发送提醒邮件
     *
     * @param to       发送目标
     * @param cc       抄送目标
     * @param title    主题
     * @param mailBody 内容
     */
    @Async
    public void sendEmail(String to, String cc, String title, String mailBody) {
        MailSender.sendNoticeEmail(to, cc, title, mailBody);
    }
}

启动时执行代码

package com.zero.testing;

import com.zero.testing.job.MailSenderJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.Resource;

/**
 * @author Zero
 * @date 2019/3/20
 */
@SpringBootApplication
@Slf4j
public class TestApp implements CommandLineRunner {

    @Resource
    private MailSenderJob mailSenderJob;
    
    public static void main(String[] args) {
        SpringApplication.run(TestApp.class, args);
    }

    /**
     * Callback used to run the bean.
     *
     * @param args incoming main method arguments
     * @throws Exception on error
     */
    @Override
    public void run(String... args) throws Exception {
        log.info("{}", "启动完成");

        long a1 = System.currentTimeMillis();
        mailSenderJob.sendEmail("your_email@mail.com", "another_email@mail.com", "title", "body");
        long a2 = System.currentTimeMillis();
        log.error("cost time {}", (a2 - a1));
    }
}


--------------------------------------------------华丽的分割线--------------------------------------------------------------


文笔不好,望见谅! ^ _ ^
如有任何问题或者意见,欢迎留言交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值