SpringBoot邮箱注册

Posted 鹏星

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot邮箱注册相关的知识,希望对你有一定的参考价值。

首先在pom.xml导入依赖

<!-- springboot 邮件mail -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <version>2.7.2</version>
        </dependency>
        <!--测试类-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>

然后在application.yml写入Spring邮箱配置

spring:
#邮箱
  mail:
#默认的邮件编码
    default-encoding: UTF-8
# 设置邮箱主机(服务商),这里使用QQ邮件服务器 ---->配置 SMTP 服务器地址
    host: smtp.qq.com
#配置邮箱用户名
    username: 123@qq.com
#配置密码,注意,不是真正的密码,而是刚刚申请到的授权码
    password: *********
#SMTP 服务器的端口
    port: 587
    properties:
      mail:
        smtp:
# 必须进行授权认证,它的目的就是阻止他人任意乱发邮件
          auth: true
#SMTP加密方式:连接到一个TLS保护连接
          starttls:
            enable: true
            required: true

接下来写一个测试类emailTest

package com.haoyang.ceshi;

import com.haoyang.TcmApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.test.context.junit4.SpringRunner;

/*
 * eamil测试类
 * */

@RunWith(SpringRunner.class)
@SpringBootTest(classes = TcmApplication.class)
public class emailTest 

    @Autowired
    private JavaMailSender javaMailSender;

    @Test
    public void  send()
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        //设置发送人
        mailMessage.setFrom("123@qq.com");
        //邮件主题
        mailMessage.setSubject("灵异事件");
        //邮件内容
        mailMessage.setText("九十岁老太为何起死回生,数百头母猪为何半夜惨叫。女生宿舍为何频频失窃,超市方便面为何惨遭黑手。在达一切的背后,是人性的扭曲、还是道德的沦丧。");
        //收件人
        mailMessage.setTo("123@qq.com");
        javaMailSender.send(mailMessage);
    


注意,有些人在private JavaMailSender javaMailSender;中可能会提示报错

这个时候还要在写一个配置MailConfiguration

package com.haoyang.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

@Configuration
public class MailConfiguration 
    @Bean
    public JavaMailSender getJavaMailSender() 
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost("smtp.qq.com");
        mailSender.setPort(587);
        mailSender.setUsername("123@qq.com");
        mailSender.setPassword("*********");
        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        return mailSender;
    


运行测试类时发现报错

不要慌

 @Test
    public void  send()    //这个地方的修饰符必须是public,不能是private
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        //设置发送人
        mailMessage.setFrom("123@qq.com");
        //邮件主题
        mailMessage.setSubject("灵异事件");
        //邮件内容
        mailMessage.setText("九十岁老太为何起死回生,数百头母猪为何半夜惨叫。女生宿舍为何频频失窃,超市方便面为何惨遭黑手。在达一切的背后,是人性的扭曲、还是道德的沦丧。");
        //收件人
        mailMessage.setTo("123@qq.com");
        javaMailSender.send(mailMessage);
    

然后重新运行就可以了

SpringBoot邮箱链接注册验证

Spring Boot邮箱链接注册验证

简单介绍

注册流程
【1】前端提交注册信息
【2】后端接受数据
【3】后端生成一个UUID做为token,将token作为redis的key值,用户数据作为redis的value值,并设置key的时长
【4】后端根据用户信息中的邮箱地址信息,检验用户是否已经注册,如果没有,生成注册链接发送到用户邮箱,如果已经注册,提示用户该邮箱地址已被注册
【5】用户点击邮件中的注册链接
【6】后端判断redis中token是否过期,没有将用户信息保存到数据库,提示用户注册成功
项目源码:https://gitee.com/residual-temperature/email-link-demo.git
邮箱效果图
邮箱链接

实现过程

1、pom文件要加入的jar包

 	   <!-- 邮件相关 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-mail</artifactId>
       </dependency>

       <!-- redis相关 -->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-data-redis</artifactId>
       </dependency>

2、application.yml文件中要加入的配置

spring:        
  redis:
    host:     # redis地址
    port: 6379   # redis端口号(默认6379)
    password:     # redis密码
  mail:
    host: smtp.qq.com    # 邮箱协议
    username: 地址          # 发送的邮箱地址
    password:  授权码      # 邮箱的授权码

3、定义实体类


@Repository
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
  private long id;
  private String account;
  private String password;
  private String username;
  
}

注意

此处没有get(),set()方法是因为导入了lombok包

4、redis的config配置
对象的保存需要序列化,所以需要自定义RedisTemplete


@Configuration
public class RedisConfig {
    //编写自己的配置类
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        //为了开发方便一般使用<String,Object>
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        //JSON序列化的配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);

        //hash采用String的序列方式
        template.setHashKeySerializer(stringRedisSerializer);

        //value序列化采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);

        //hash的Value序列化采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

5、验证链接生成和邮箱发送的工具类CodeUtils的配置

@Component
public class CodeUtils {

    @Resource
    JavaMailSender mailSender;

    @Resource
    RedisTemplate<String, User> redisTemplate;

    // 生成链接,并给接收的邮箱发送邮件
    public boolean sendCode(User user){
        MimeMessage message = mailSender.createMimeMessage();
        try{
            MimeMessageHelper messageHelper = new MimeMessageHelper(message);
            String token = UUID.randomUUID().toString(); // 生成UUID
            redisTemplate.opsForValue().set(token,user);
            redisTemplate.expire(token,300, TimeUnit.SECONDS);
            messageHelper.setFrom("发送方的邮箱地址"); //发送方的邮箱地址,而不是接收方的邮箱地址
            messageHelper.setTo(user.getAddress()); // 接收方的邮箱地址
            messageHelper.setSubject("注册");  // 邮箱标题
            String html = "<html>\\n" +
                    "<body>\\n" +
                    "<p>请点击下方链接注册</p>\\n" +
                    "<a href=\\"http://localhost:8081/lookCode/"+token+"\\">http://localhost:8081/lookCode/"+token+"</a>" +
                    "</body>\\n" +
                    "</html>";
            messageHelper.setText(html,true); // 邮箱内容
            mailSender.send(message);  // 发送邮箱
            System.out.println("发送成功");
            return true;
        }catch (Exception e){
            System.out.println("发送失败");
            return false;
        }
    }

    // 判断token是否过期
    public boolean eqToken(String token){
        return redisTemplate.hasKey(token);
    }

    // 根据token查询用户的信息
    public User findUser(String token){
        return redisTemplate.opsForValue().get(token);
    }

}

6、UserMapper的配置

@Mapper
@Repository
public interface UserMapper {

    // 添加用户 注解开发sql语句
    @Insert("insert into user(account,password,username) values (#{account},#{password},#{username})")
    public int addUser(User user);

}


7、UserService的配置

public interface UserService {

    // 添加用户
    public boolean adduser(User user);

    // 根据用户注册信息进行注册链接的的生成和发送
    public boolean sendCode(User user);

    // 用户点击注册链接判断token是否过期
    public boolean eqToken(String token);

}

8、UserService的实现类UserServiceImpl的配置

@Service
public class UserServiceImpl implements UserService {

    @Resource
    UserMapper userMapper;

    @Resource
    CodeUtils codeUtils;

    /**
     * 添加注册的用户信息
     * @param user 注册的用户信息
     * @return 是否添加成功
     */
    @Override
    public boolean adduser(User user) {
        return userMapper.addUser(user) > 0;
    }

    /**
     * 生成链接和发送链接
     * @param address 接收的邮箱地址
     * @param user 注册的用户信息
     */
    @Override
    public boolean sendCode(User user) {
       if ( codeUtils.sendCode(user)) // 调用验证链接生成工具类中的生成链接和发送邮件函数
           return true;
       else
           return false;
    }

    /**
     * 判断token是否过期
     * @param token 用户注册所接收的token
     * @return 注册成功与否
     */
    @Override
    public boolean eqToken(String token) {
        boolean flag = codeUtils.eqToken(token);

        if (flag){
            User user = codeUtils.findUser(token);
            adduser(user);
            return true;
        }else {
            return false;
        }
    }
}


9、UserController的配置

@RestController
public class UserController {

    @Resource
    UserService userService;

    // 根据用户注册信息进行注册链接的的生成和发送
    @PostMapping("/sendCode")
    public Map<String,String> sendCode(@RequestBody User user){
        boolean flag = userService.sendCode(user);
        Map<String,String> map = new HashMap<>();
        if (flag){
            map.put("msg","邮件发送成功,请前往您的邮箱进行注册验证");
            return map;
        }else {
            map.put("msg","邮件发送失败");
            return map;
        }
    }

    // 判断是否注册成功
    @GetMapping("/lookCode/{token}")
    public Map<String,String> lookCode(@PathVariable("token")String token){
        boolean flag = userService.eqToken(token);
        Map<String,String> map = new HashMap<>();
        if (flag){
            map.put("msg","注册成功");
            /* 后续的操作 ... ...*/
            return map;
        }else {
            map.put("msg","注册码过期,请重新注册");
            return map;
        }
    }
}

因为没有写前端页面,所以就用postman和页面来演示

postman测试

传入user对象

user对象的传入

返回结果

发送链接成功

邮箱链接

邮箱链接

点击注册链接之后

注册成功

注册成功之后数据库前后对比

注册成功之前
插入之前
注册成功之后
插入页面

总结

可能会遇到的问题
【1】有些内部网络不支持发送邮箱,如果保证代码没错,可以换个网络试试
【2】如果是在本地测试,连接的是本地redis,记得开启本地的redis

以上是关于SpringBoot邮箱注册的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot轻轻松松搞定用户邮箱登录注册

SpringBoot轻轻松松搞定用户邮箱登录注册

SpringBoot邮箱注册

SpringBoot进阶邮件服务(实战模拟邮箱注册含源码)

SpringBoot实战项目杂货铺登陆注册邮箱验证整合Redis

SpringBoot中快速实现邮箱发送