Spring boot 2. X Series tutorial 70 -- implementing the function of registered user sending activation email in spring boot

In the previous chapter, I took you to learn how to send various types of emails in spring boot. Next, I took you to implement the email sending function in actual development.

Demand analysis:
When many websites register, they will send an activation email to our registered mailbox, which is a series of links. You can log in after clicking the link activation. Today we will realize this function.

1, Implementation steps of sending activation mail

1. Create a web project

According to the previous experience, we create a web program and transform it into a Spring Boot project. The specific process is outlined.

2. Add dependency package

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--MySQL-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--Druid Database connection pool-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mail-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

3. Create application.yml configuration file

Rewrite the configuration of database in the configuration file into your own configuration information.

spring:
  http:
    encoding:
      charset: UTF-8
      force: true
      enabled: true
  datasource:
    url: jdbc:mysql://localhost:3306/db6?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: syc
    driverClassName: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  jpa:
    database: mysql
    show-sql: true
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    database-platform: org.hibernate.dialect.MySQL5Dialect
  #Page template configuration  
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
  mail:
    host: smtp.qq.com
    from: 2312119590@qq.com
    username: 2312119590@qq.com
    password: xxx(Own authorization code)
    protocol: smtp
    default-encoding: UTF-8
server:
  tomcat:
    uri-encoding: UTF-8

4. Encapsulate User entity class

package com.yyg.boot.entity;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@Data
@Entity
@Table(name = "user")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String username;

    private String password;

    @Column(name = "usermail")
    private String userMail;

    /**
     * Status: 0 for inactive, 1 for active
     */
    private Integer status;

    /**
     * Use UUID to generate a number and send it to the user's mailbox. When the user clicks the link, make another verification,
     * If the code from the user is the same as the code we sent, change the status to "1" to activate the user
     */
    private String  code;

}

5. Configure data source

package com.yyg.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druidConfig(){
        return new DruidDataSource();
    }

}

6. Create a JPA warehouse class

package com.yyg.boot.repository;

import com.yyg.boot.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@Repository
public interface UserRepository  extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User> {

    User findUserByCode(String code);

    User findByUsernameAndPassword(String username,String password);

}

7. Create a tool class to generate UUID

package com.yyg.boot.utils;

import java.util.UUID;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
public class UUIDUtil {

    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-","");
    }

}

8. Define the tool class for sending mail

Define the interface of sending mail tool class

package com.yyg.boot.mail;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Encapsulate an email interface, convenient to call directly after
 */
public interface IMailService {

    /**
     * Send text message
     *
     * @param to      addressee
     * @param subject theme
     * @param content content
     */
    void sendSimpleMail(String to, String subject, String content);

    /**
     * Send HTML message
     *
     * @param to      addressee
     * @param subject theme
     * @param content content
     */
    void sendHtmlMail(String to, String subject, String content);

    /**
     * Send mail with attachments
     *
     * @param to       addressee
     * @param subject  theme
     * @param content  content
     * @param filePath enclosure
     */
    void sendAttachmentsMail(String to, String subject, String content, String filePath);

    /**
     * Send template mail
     * @param to addressee
     * @param subject theme
     * @param fileName Mail template file name
     * @param model Mail data carrier
     */
    void sendModelMail(String to, String subject, String fileName, Object model);

}

Implement sending mail tool class

package com.yyg.boot.mail.impl;

import com.yyg.boot.mail.IMailService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Objects;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@Slf4j
@Service
public class IMailServiceImpl implements IMailService {

    /**
     * Spring Boot It provides a simple and abstract way to send mail. It uses the following interface, which can be directly injected here
     */
    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private Configuration configuration;

    /**
     * My qq mailbox in profile
     */
    @Value("${spring.mail.from}")
    private String from;

    /**
     * Simple text mail
     *
     * @param to      addressee
     * @param subject theme
     * @param content content
     */
    @Override
    public void sendSimpleMail(String to, String subject, String content) {
        //Create a SimpleMailMessage object
        SimpleMailMessage message = new SimpleMailMessage();
        //Email sent by
        message.setFrom(from);
        //Mail recipient
        message.setTo(to);
        //Message subject
        message.setSubject(subject);
        //Message content
        message.setText(content);
        //Send mail
        mailSender.send(message);
    }

    /**
     * html mail
     *
     * @param to      addressee
     * @param subject theme
     * @param content content
     */
    @Override
    public void sendHtmlMail(String to, String subject, String content) {
        //Get MimeMessage object
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper;
        try {
            messageHelper = new MimeMessageHelper(message, true);
            //Email sent by
            messageHelper.setFrom(from);
            //Mail recipient
            messageHelper.setTo(to);
            //Message subject
            message.setSubject(subject);
            //Message content, html format
            messageHelper.setText(content, true);
            //send out
            mailSender.send(message);
            //log information
            log.info("Message sent...");
        } catch (MessagingException e) {
            log.error("Exception sending mail!", e);
        }
    }

    /**
     * Mail with attachments
     * @param to       addressee
     * @param subject  theme
     * @param content  content
     * @param filePath enclosure
     */
    @Override
    public void sendAttachmentsMail(String to, String subject, String content, String filePath) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            //FileSystemResource file = new FileSystemResource(new File(filePath));
            ClassPathResource resource = new ClassPathResource(filePath);
            FileSystemResource file = new FileSystemResource(resource.getFile());
            helper.addAttachment(Objects.requireNonNull(file.getFilename()), file);
            //You can add multiple attachments at the same time. Just add the 2nd, 3rd... Attachments here
            //helper.addAttachment(fileName2, file2);
            mailSender.send(message);
            //log information
            log.info("Message sent...");
        } catch (MessagingException e) {
            log.error("Exception sending mail!", e);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("Exception sending mail!", e);
        }
    }

    @Override
    public void sendModelMail(String to, String subject, String fileName, Object model) {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);

            Template template = configuration.getTemplate(fileName);
            String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);

            helper.setText(html, true);

            mailSender.send(mimeMessage);

            //log information
            log.info("Message sent...");
        } catch (MessagingException e) {
            log.error("Exception sending mail!", e);
        } catch (TemplateException e) {
            e.printStackTrace();
            log.error("Exception sending mail!", e);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

9. Define Service and its implementation

Define UserService interface

package com.yyg.boot.service;

import com.yyg.boot.entity.User;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
public interface UserService {

    /**
     * User registration,
     * @param user
     */
    void register(User user);

    /**
     * Query the user according to the activation code, and then modify the status
     */
    User checkCode(String code);

    /**
     * Activate the account and modify the user status to "1"
     */
    void updateUserStatus(User user);

    /**
     * Sign in
     */
    User login(User user);

}

Define UserServiceImpl implementation

package com.yyg.boot.service.impl;

import com.yyg.boot.entity.User;
import com.yyg.boot.mail.IMailService;
import com.yyg.boot.repository.UserRepository;
import com.yyg.boot.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userDao;

    /**
     * Injection mail interface
     */
    @Autowired
    private IMailService mailService;

    /**
     * Users register and send an activation email at the same time
     */
    @Override
    public void register(User user) {
        userDao.save(user);
        //Get activation code
        String code = user.getCode();
        log.warn("code:"+code);
        //theme
        String subject = "Activation email from one brother website";
        //User / checkcode? Code = code (activation code) is that we click the email link and then query the user according to the activation code. If the instructions are consistent, change the user status to "1" for activation
        //The above activation code is sent to the user registration email
        //Note: the link address here is the internal address of the project. If we don't have a formal server address, we can't jump to the activation page of our own project from the qq mailbox for the moment
        String context = "<a href=\"http://localhost:8080/user/checkCode?code= "+ code +" \ "> to activate, please click:" + code + "< / a >";
        //Send activation email
        mailService.sendHtmlMail (user.getUserMail(),subject,context);
    }

    /**
     * Query the user according to the activation code, and then modify the status
     */
    @Override
    public User checkCode(String code) {
        return userDao.findUserByCode(code);
    }

    /**
     * Activate account and modify user status
     */
    @Override
    public void updateUserStatus(User user) {
        userDao.saveAndFlush(user);
    }

    /**
     * Sign in
     */
    @Override
    public User login(User user) {
        User u = userDao.findByUsernameAndPassword(user.getUsername(),user.getPassword());
        if (u !=null){
            return u;
        }
        return null;
    }

}

10. Define the interface to jump to the homepage

package com.yyg.boot.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@Controller
public class IndexController {

    @RequestMapping(value = "/")
    public String index(){

        return "index";
    }

}

11. Define core business interface

package com.yyg.boot.web;

import com.yyg.boot.entity.User;
import com.yyg.boot.service.UserService;
import com.yyg.boot.utils.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * register
     */
    @PostMapping(value = "/registerUser")
    public String register(User user){
        user.setStatus(0);
        String code = UUIDUtil.getUUID();
        user.setCode(code);
        userService.register(user);
        return "success";
    }

    /**
     * Verify code activation account in email
     * First query the user according to the activation code, and then change the status to "1"
     */
    @GetMapping(value = "/checkCode")
    public String checkCode(String code){
        User user = userService.checkCode(code);
        //If the user is not equal to null, change the user status to status=1
        if (user !=null){
            user.setStatus(1);
            //Clear the code verification code. It is no longer needed
            user.setCode("");
            userService.updateUserStatus(user);
        }
        return "login";
    }

    /**
     * Jump to login page
     * @return login
     */
    @GetMapping(value = "/loginPage")
    public String login(){
        return "login";
    }

    /**
     * Sign in
     */
    @RequestMapping(value = "/loginUser")
    public String login(User user){
        User u = userService.login(user);
        if (u !=null){
            return "welcome";
        }
        return "login";
    }

}

12. Create html page

index.html page

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>register</title>
</head>
<body>
<form action="/user/registerUser" method="post">
    user name:<input type="text" id="username" name="username"/><br>
    password:<input type="password" id="password" name="password"/><br>
    Email:<input type="email" id="usermail" name="userMail"><br>
    <input type="submit" value="register">
</form>
<a href="/user/loginPage">Sign in</a>
</body>
</html>

login.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sign in</title>
</head>
<body>
<form action="/user/loginUser" method="post">
    user name:<input type="text" id="username" name="username"/><br>
    password:<input type="password" id="password" name="password"/><br>
    <input type="submit" value="Sign in">
</form>
</body>
</html>

success.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login was successful</title>
</head>
<body>
//Go to email to activate account
</body>
</html>

welcome.html page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>welcome</title>
</head>
<body>
//Login successful
</body>
</html>

13. Create entry class

package com.yyg.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @Author Brother Sun
 * @Date Created in 2020/4/20
 * @Description Description
 */
@SpringBootApplication
public class CheckMailApplication {

    public static void main(String[] args){
        SpringApplication.run(CheckMailApplication.class,args);
    }

}

14. Complete project structure

15. Start the program and carry out the test

Enter Homepage

You can register a new user in the homepage

login was successful

You can see a new user in the database.

And an activation email was also received in the mailbox.

be careful:

Because our project is not online, the activation link belongs to the internal link of the project, and Tencent mailbox belongs to the outsourcing application, so we can't realize the jump temporarily. When the follow-up project goes online, with the real server address, you can change the email link to your own server address, and then you can realize the jump, and then modify the user's status value in your database.
In our case, we only do demonstration, logic is no problem!

Tags: Spring MySQL Database Java

Posted on Thu, 18 Jun 2020 06:13:27 -0400 by dgwade