Spring boot mail + QQ邮箱实现报警邮件发送

821 阅读2分钟

依赖

使用springboot提供的mail starter.

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
              <version>2.3.4.RELEASE</version>
        </dependency>

该依赖同时包含了如下几个依赖

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.3.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>5.2.9.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.sun.mail</groupId>
      <artifactId>jakarta.mail</artifactId>
      <version>1.6.5</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

看出已经包含了mail组件,不需要自己再引入其他的包.

代码

  • application.yml配置相关参数

    mail:
      from: 233333333@qq.com
      host: smtp.qq.com
      port: 587
      username: 233333333@qq.com
      password: giyzthpqvzbh553
      to: 233333333@qq.com
    

    QQ邮箱对于设置的参考为:

    如何设置IMAP服务的SSL加密方式?
    使用SSL的通用配置如下:
    接收邮件服务器:imap.qq.com,使用SSL,端口号993
    发送邮件服务器:smtp.qq.com,使用SSL,端口号465或587
    账户名:您的QQ邮箱账户名(如果您是VIP帐号或Foxmail帐号,账户名需要填写完整的邮件地址)
    密码:您的QQ邮箱密码
    电子邮件地址:您的QQ邮箱的完整邮件地址
    

    ps:这里的端口号我选择的是587,但是qq邮箱的设置界面提供了两个端口.匹配规则为:

    • smtp -> 587
    • smtps -> 465

    如果使用smtps加587,会直接报这个错,其实还好,因为是马上报错并指出错误信息.

    Exception in thread "mailTaskExecutor-1" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: smtp.qq.com, port: 587;
    

    如果是使用smt+465,会在延迟一段时间后报错:

    Exception in thread "mailTaskExecutor-1" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Got bad greeting from SMTP host: smtp.qq.com, port: 465, response: [EOF].
    

    并没有说的很清楚错误原因,很让人迷惑.

  • QQ邮箱设置

    在设置->账户中找到一下设置,根据需求开启.

image.png

生成的授权码即为在别处登录qq邮箱的`密码`.
  • 将配置提取出来.

    将配置放在application.yml文件中.这样修改邮件发送配置时就不需要频繁改动这个com.kyw7.common通用包.

    package com.kyw7.common
    @Component
    public class MailConfig {
      @Value("${mail.to}")
      private String[] to;
      @Value("${mail.from}")
      private String from;
      @Value("${mail.host}")
      private String host;
      @Value("${mail.port}")
      private int port;
      @Value("${mail.username}")
      private String username;
      @Value("${mail.password}")
      private String password;
      // 省略getter,setter
    }
    

    ps:除去to代表的是收件人的信息,其余的信息均是发件人的相关信息.

  • 包装一下具体发送类

    空出了标题和内容,内容的模板放在使用MailSender的类中去定义.

    @Component
    public class MailSender {
      @Autowired
      MailConfig config;
    ​
      public void sendSimpleMessage(String subject, String text) {
    ​
        SimpleMailMessage message = new SimpleMailMessage();
    ​
        message.setFrom(config.getFrom());
        message.setTo(config.getTo());
        message.setSubject(subject);
        message.setText(text);
    ​
        JavaMailSender().send(message);
      }
    ​
    ​
      public JavaMailSender JavaMailSender() {
    ​
        JavaMailSenderImpl emailSender = new JavaMailSenderImpl();
        emailSender.setHost(config.getHost());
        emailSender.setPort(config.getPort());
        emailSender.setUsername(config.getUsername());
        emailSender.setPassword(config.getPassword());
    ​
        Properties props = emailSender.getJavaMailProperties();
        //默认使用tls的方式,直接写死,不提供非tls方式
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.required", "true");
        props.put("mail.smtp.starttls.enable", "true");
    ​
        return emailSender;
      }
    }
    

使用

sender.sendSimpleMessage(subject, content);