08.`spring boot`邮件服务

1. 登录邮箱获取授权
  1. 开启POP3/SMTP服务

    开启服务

  2. 获取授权码,要记好,要用到

    授权密码

2. 依赖
  1. 依赖

    <!-- 邮箱服务 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>    
    
  2. 说明

    1. spring boot已经集成,无需声明版本

    2. 本项目用到了RocketMq

      <properties>
          <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
      </properties>
      
      <!-- spring-cloud-rocketmq -->
      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
      </dependency>
      
      <dependencyManagement>
          <dependencies>
              <!-- spring-cloud-alibaba-dependencies -->
              <dependency>
                  <groupId>com.alibaba.cloud</groupId>
                  <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                  <version>${spring-cloud-alibaba.version}</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
      </dependencyManagement>
      
3. 配置文件
  1. email-provider

    1. 主配置文件application.yml

      server:
        port: 8081
      
      spring:
        application:
          name: email-provider
        cloud:
          stream:
            rocketmq:
              binder:
                name-server: 120.25.207.44:9876
            bindings:
              emailOutput: {destination: email-topic, content-type: application/json} 
      
    2. 启动类

      import com.sheng.cloud.consumer.binding.EmailSource;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.stream.annotation.EnableBinding;
      
      @EnableBinding({EmailSource.class})
      @SpringBootApplication
      public class EmailProviderApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(EmailProviderApplication.class, args);
          }
      
      }        
      
      • 将自定义bingding注册到容器
  2. email-consumer

    1. 主配置文件

      server:
        port: 8082
      
      spring:
        application:
          name: email-consumer
        cloud:
          stream:
            rocketmq:
              binder:
                # 配置 rocketMq 的 nameserver 服务器地址
                name-server: 120.25.207.44:9876
            bindings:
              # 自定义,要与提供者的 binding 一致
              emailInput: {destination: email-topic, content-type: application/json, group: email-group}
        # 邮件服务的配置        
        mail:
          # 这是 163 邮箱的 SMTP 服务器:smtp.163.com
          host: smtp.163.com
          # 邮箱,如 xx@163.com
          username: <邮箱>
          # 邮箱的授权码
          password: <开启POP3/SMTP服务时的授权码>
          properties:
            mail:
              smtp:
                auth: true
                starttls:
                  enable: true
                  required: true
        # redis 的配置            
        redis:
          # redis 的地址
          host: 127.0.0.1
          # redis 的端口
          port: 6379
          # 密码
          password: password
          # 第几个数据库
          database: 1
          # 连接池
          lettuce:
            pool:
              min-idle: 5
              max-active: 10        
      
      • 虽然是导入redis外部服务,但是还是要配置reids,否则依然是redis的默认配置
      • spring.mail.username为邮箱
      • spring.mail.password开启POP3/SMTP服务时的授权码,不是邮箱密码
    2. 启动类

      import com.sheng.cloud.consumer.binding.EmailSink;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.stream.annotation.EnableBinding;
      
      @EnableBinding({EmailSink.class})
      @SpringBootApplication(scanBasePackages = {"com.sheng.redis.provider", "com.sheng.cloud.consumer"})
      public class EmailConsumerApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(EmailConsumerApplication.class, args);
          }
      
      }        
      
      • 将自定义binding注册到容器
      • @SpringBootApplication注解要使用scanBasePackages = {}把要扫描的主包注册,在本项目因为redis单独成为一个服务,将其安装到了本地仓库,所以必须要使用scanBasePackages属性,否则会报类找不到的错误,服务启动失败
4. 邮件服务
  1. 发送普通文本

    1. EmailServiceImpl实现类

      import com.sheng.cloud.consumer.common.StatusCodeEnum;
      import com.sheng.cloud.consumer.constant.EmailConstant;
      import com.sheng.cloud.consumer.domian.dto.EmailDto;
      import com.sheng.cloud.consumer.exception.ServiceException;
      import com.sheng.cloud.consumer.service.EmailService;
      import com.sheng.cloud.consumer.utils.RandomNumberUtils;
      import com.sheng.cloud.consumer.utils.RedisUtils;
      import com.sheng.redis.provider.service.RedisService;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.cloud.stream.annotation.StreamListener;
      import org.springframework.mail.MailException;
      import org.springframework.mail.SimpleMailMessage;
      import org.springframework.mail.javamail.JavaMailSender;
      import org.springframework.stereotype.Service;
      
      import javax.annotation.Resource;
      import java.util.Date;
      import java.util.concurrent.TimeUnit;
      
      /**
       * 说明:
       *
       * @author sheng
       */
      @Service
      public class EmailServiceImpl implements EmailService {
          @Resource
          private RedisService redisService;
          @Resource
          private JavaMailSender javaMailSender;
          @Value("${spring.mail.username}")
          private String username;
      
          @Override
          @StreamListener("emailInput")
          public void sendEmail(EmailDto emailDto) throws Exception {
              // 验证码
              String token = RandomNumberUtils.sixFigures();
              // 目标邮箱
              String email = emailDto.getEmail();
              // 隐私原因,截取
              String[] emailSplit = email.split("@");
              // 判断是否是正确的邮箱
              int length = 2;
              if (emailSplit.length > length) {
                  throw new ServiceException(StatusCodeEnum.PARAMS_IS_INVALID);
              }
              // 邮箱的前几位
              String emailSon = emailSplit[0];
              // 隐私邮箱
              String privacyEmail = emailSon.substring(0, 2)
                      + "**"
                      + emailSon.substring(emailSon.length() - 1)
                      + "@" + emailSplit[1];
              // 封装发送的信息
              SimpleMailMessage message = new SimpleMailMessage();
              // 标题
              message.setSubject(EmailConstant.EMAIL_SUBJECT);
              // 发送人
              message.setFrom(username);
              // 目标邮箱
              message.setTo(email);
              // 发送的文本
              message.setText(EmailConstant.EMAIL_TEXT_1
                      + privacyEmail
                      + EmailConstant.EMAIL_TEXT_2
                      + token
                      + EmailConstant.EMAIL_TEXT_3);
              // 发送的时间
              message.setSentDate(new Date());
              // 发送信息
              // try 发送失败不会重试
              try {
                  javaMailSender.send(message);
              } catch (MailException e) {
                  e.printStackTrace();
              }
              // redis 验证码过期时间
              int timeout = 15;
              // 将验证码存储到 redis
              redisService.set(RedisUtils.emailKey(email), token, timeout, TimeUnit.MINUTES);
          }
      }        
      
    2. 说明

      1. org.springframework.mail.javamail.JavaMailSender对象的send()方法来发送消息

      2. org.springframework.mail.SimpleMailMessage用来封装邮件内容信息

        1. setFrom()方法,必须传入跟主配置文件application.yml填写的授权码的那个邮箱,否则报550错误
        2. setSubject()邮件的标题
        3. setText()邮件正文的内容
        4. setTo()目标邮箱
        5. setSentDate()邮件的时间
      3. 发送邮件的代码

        // 封装发送的信息
        SimpleMailMessage message = new SimpleMailMessage();
        // 标题
        message.setSubject(EmailConstant.EMAIL_SUBJECT);
        // 发送人
        message.setFrom(username);
        // 目标邮箱
        message.setTo(email);
        // 发送的文本
        message.setText(EmailConstant.EMAIL_TEXT_1
                + privacyEmail
                + EmailConstant.EMAIL_TEXT_2
                + token
                + EmailConstant.EMAIL_TEXT_3);
        // 发送的时间
        message.setSentDate(new Date());
        // 发送信息
        // try 发送失败不会重试
        try {
            javaMailSender.send(message);
        } catch (MailException e) {
            e.printStackTrace();
        }            
        
    3. 结果

      结果

  2. 发送html

    1. EmailServiceImpl实现类

      import com.sheng.cloud.consumer.common.StatusCodeEnum;
      import com.sheng.cloud.consumer.constant.EmailConstant;
      import com.sheng.cloud.consumer.domian.dto.EmailDto;
      import com.sheng.cloud.consumer.exception.ServiceException;
      import com.sheng.cloud.consumer.service.EmailService;
      import com.sheng.cloud.consumer.utils.RandomNumberUtils;
      import com.sheng.cloud.consumer.utils.RedisUtils;
      import com.sheng.redis.provider.service.RedisService;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.cloud.stream.annotation.StreamListener;
      import org.springframework.mail.javamail.JavaMailSender;
      import org.springframework.mail.javamail.MimeMessageHelper;
      import org.springframework.stereotype.Service;
      
      import javax.annotation.Resource;
      import javax.mail.internet.MimeMessage;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.concurrent.TimeUnit;
      
      /**
       * 说明:
       *
       * @author sheng
       */
      @Service
      public class EmailServiceImpl implements EmailService {
          @Resource
          private RedisService redisService;
          @Resource
          private JavaMailSender javaMailSender;
          @Value("${spring.mail.username}")
          private String username;
      
          @Override
          @StreamListener("emailInput")
          public void sendEmail(EmailDto emailDto) throws Exception {
              // 验证码
              String token = RandomNumberUtils.sixFigures();
              // 目标邮箱
              String email = emailDto.getEmail();
              // 隐私原因,截取
              String[] emailSplit = email.split("@");
              // 判断是否是正确的邮箱
              int length = 2;
              if (emailSplit.length > length) {
                  throw new ServiceException(StatusCodeEnum.PARAMS_IS_INVALID);
              }
              // 邮箱的前几位
              String emailSon = emailSplit[0];
              // 隐私邮箱
              String privacyEmail = emailSon.substring(0, 2)
                      + "**"
                      + emailSon.substring(emailSon.length() - 1)
                      + "@" + emailSplit[1];
              // 封装发送的信息,发送 html 页面
              MimeMessage message = javaMailSender.createMimeMessage();
              MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true, "utf-8");
              // 标题
              mimeMessageHelper.setSubject(EmailConstant.EMAIL_SUBJECT);
              // 发送人
              mimeMessageHelper.setFrom(username);
              // 目标邮箱
              mimeMessageHelper.setTo(email);
              // 发送的文本
              mimeMessageHelper.setText(EmailConstant.EMAIL_TEXT_1
                              + privacyEmail
                              + EmailConstant.EMAIL_TEXT_2
                              + token
                              + EmailConstant.EMAIL_TEXT_3
                              + EmailConstant.EMAIL_FROM
                              + new SimpleDateFormat("yyyy年MM月dd日").format(new Date())
                      , true);
              // 发送的时间
              mimeMessageHelper.setSentDate(new Date());
              // 发送信息
              // try 发送失败不会重试
              javaMailSender.send(message);
              // redis 验证码过期时间
              int timeout = 15;
              // 将验证码存储到 redis
              redisService.set(RedisUtils.emailKey(email), token, timeout, TimeUnit.MINUTES);
          }
      }
      
    2. 说明

      1. org.springframework.mail.javamail.MimeMessageHelper封装html邮件内容

      2. javax.mail.internet.MimeMessage发送的信息

      3. 发送邮件的代码

        // 封装发送的信息,发送 html 页面
        MimeMessage message = javaMailSender.createMimeMessage();
        // 封装 html 邮件内容
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true, "utf-8");
        // 标题
        mimeMessageHelper.setSubject(EmailConstant.EMAIL_SUBJECT);
        // 发送人
        mimeMessageHelper.setFrom(username);
        // 目标邮箱
        mimeMessageHelper.setTo(email);
        // 发送的文本
        mimeMessageHelper.setText(EmailConstant.EMAIL_TEXT_1
                        + privacyEmail
                        + EmailConstant.EMAIL_TEXT_2
                        + token
                        + EmailConstant.EMAIL_TEXT_3
                        + EmailConstant.EMAIL_FROM
                        + new SimpleDateFormat("yyyy年MM月dd日").format(new Date())
                , true);
        // 发送的时间
        mimeMessageHelper.setSentDate(new Date());
        // 发送信息
        // try 发送失败不会重试
        javaMailSender.send(message);            
        
    3. 结果

      结果

5. mail-demo 源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值