catalogue
1. Use Springboot to send template mail and test
2. Configure application properties
4. Write mail sending tool class
2. Add @ Async annotation on the method of sending mail by mail tool class
3. Realize mailbox registration function
3.1 click Register to send the email and password to the back end
3.2. The backend processes the request, encapsulates the result into Ajax result and returns it
4. Realize the mailbox activation function
4.1 click the activation link in the email to jump to the activation page
3. Complete process of mailbox registration and activation
1. Enter the registration page and click Register
2. Enter the mailbox and check the mail
3. Click the link in the email to complete user activation
4. Activate successfully, jump to the login interface:
1. Send template mail using Springboot and test
1. Add dependency
<!--mail--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!--thymeleaf--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
2. Configure application properties
You need to obtain the email authorization code. I won't talk about it in detail here
# Set mailbox host (service provider) spring.mail.host=smtp.qq.com # Set user name spring.mail.username=xxx@qq.com # Set the password. The password here is the authorization code of QQ mailbox to open SMTP instead of QQ password spring.mail.password=xxx # Set code spring.mail.default-encoding=UTF-8 #Sender # Authorization authentication must be carried out. Its purpose is to prevent others from sending emails arbitrarily spring.mail.properties.mail.smtp.auth=true #SMTP encryption method: connect to a TLS protected connection spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true # JavaMailSender configuration spring.mail.port=465 #SSL configuration spring.mail.protocol=smtp spring.mail.properties.mail.smtp.ssl.enable=true spring.mail.properties.mail.smtp.socketFactory.port=465 spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
3. Write HTML mail template
Put the template page in the templates directory under resources
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Activate mail</title> <style type="text/css"> * { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, Helvetica, sans-serif; } body { background-color: #ECECEC; } .container { width: 800px; margin: 50px auto; } .header { height: 80px; background-color: #49bcff; border-top-left-radius: 5px; border-top-right-radius: 5px; padding-left: 30px; } .header h2 { padding-top: 25px; color: white; } .content { background-color: #fff; padding-left: 30px; padding-bottom: 30px; border-bottom: 1px solid #ccc; } .content h2 { padding-top: 20px; padding-bottom: 20px; } .content p { padding-top: 10px; } .footer { background-color: #fff; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; padding: 35px; } .footer p { color: #747474; padding-top: 10px; } </style> </head> <body> <div class="container"> <div class="header"> <h1>Welcome to pet home!</h1> </div> <div class="content"> <h2>Dear user,Hello!!</h2> <p>Your email:<b><span th:text="${email}"></span></b></p> <p>Your activation code:<b><span th:text="${code}"></span></b></p> <p>Date you registered:<b><span th:text="${createTime}"></span></b></p> <P><b>Please complete activation within 10 minutes:<a href="http://127.0.0.1:8083/activation. HTML "> Click me to activate < / a > < / b > < / P > <p></p> <p>When you use this website, you must abide by laws and regulations</p> <p>If you have any questions, you can contact the administrator, Email: <b>r1624603357@126.com</b></p> </div> <div class="footer"> <p>This is a system email, please do not reply</p> <p>Please take good care of your information to avoid being stolen by others</p> <p>©Rk</p> </div> </div> </body> </html>
4. Write mail sending tool class
package com.rk.pethome.basic.util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import javax.mail.internet.MimeMessage; import java.util.Map; @Component public class SendMailUtil { //Sender private String sender="1624603357@qq.com"; @Autowired JavaMailSender javaMailSender; @Autowired TemplateEngine templateEngine; /** * Send mail * @param receiver addressee * @param subject Mail title * @param emailTemplate HTML Template * @param dataMap Data in template * @throws Exception */ //@Async / / send annotation asynchronously public void sendTemplateMail(String receiver, String subject, String emailTemplate, Map<String, Object> dataMap) throws Exception { Context context = new Context(); for (Map.Entry<String, Object> entry : dataMap.entrySet()) { context.setVariable(entry.getKey(), entry.getValue()); } String templateContent = templateEngine.process(emailTemplate, context); MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(sender); helper.setTo(receiver); helper.setSubject(subject); helper.setText(templateContent, true); javaMailSender.send(message); } }
5. Testing
package com.rk.pethome.mail; import com.rk.pethome.basic.util.SendMailUtil; import com.rk.pethome.basic.util.StrUtils; 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.mail.javamail.MimeMessageHelper; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.mail.internet.MimeMessage; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; @SpringBootTest @RunWith(SpringJUnit4ClassRunner.class) public class MailSenderTest { @Autowired private SendMailUtil mailUtil; //addressee private final String receiver = "1624603357@qq.com"; @Test public void testTemplateMail(){ //Send mail SimpleDateFormat sdf = new SimpleDateFormat("yyyy year MM month dd day HH Time mm branch ss second"); String subject = "Pet home--User registration"; String emailTemplate = "registerTemplate"; String code = StrUtils.getRandomString(5); Map<String, Object> dataMap = new HashMap<>(); dataMap.put("email", receiver); dataMap.put("code", code); dataMap.put("createTime", sdf.format(new Date())); try { mailUtil.sendTemplateMail(receiver, subject, emailTemplate, dataMap); System.out.println("Send complete"); } catch (Exception e) { e.printStackTrace(); return; } } }
2. In the user's email registration business - use multithreading to send account activation email asynchronously
1. Configure thread pool
package com.rk.pethome.basic.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @Configuration @EnableAsync // Enable asynchronous tasks public class AsyncConfiguration { // Declare a thread pool (and specify the name of the thread pool) @Bean("taskExecutor") public Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //Number of core threads 5: the number of threads initialized when the thread pool is created executor.setCorePoolSize(5); //Maximum number of threads 5: the maximum number of threads in the thread pool. Threads exceeding the number of core threads will be applied only after the buffer queue is full executor.setMaxPoolSize(5); //Buffer queue 500: a queue used to buffer the execution of tasks executor.setQueueCapacity(500); //Allow thread idle time of 60 seconds: threads beyond the core thread will be destroyed after the idle time arrives executor.setKeepAliveSeconds(60); //Prefix of thread pool name: after setting, it is convenient for us to locate the thread pool where the processing task is located executor.setThreadNamePrefix("DailyAsync-"); executor.initialize(); return executor; } }
2. Add @ Async annotation on the method of sending mail by mail tool class
3. Realize mailbox registration function
3.1 click Register to send the email and password to the back end
//Register users via email emilReg(){ //Get parameters let para = Object.assign({}, this.user); //Send request this.$http.post("/user/registerByEmial",para).then((res)=>{ console.debug(res); console.debug(para); let {success,msg}=res.data; if(!success)//If it fails { this.errorMsg=msg; }else{ //Clear error message this.errorMsg=""; //location.href="login.html"; } }); },
3.2. The backend processes the request, encapsulates the result into Ajax result and returns it
AjaxResult:
@Data @NoArgsConstructor @AllArgsConstructor public class AjaxResult { private Boolean success=true; private String msg; //Result value returned to the front end private Object result; public AjaxResult(Boolean success,String msg) { this.success=success; this.msg=msg; } public AjaxResult setResult(Object result){ this.result=result; return this; } }
Controller layer:
@RestController @RequestMapping("/user") public class UserController { @Autowired private IUserService userService; /** * Register via email * @param userDot * @return */ @PostMapping("/registerByEmial") public AjaxResult registerByEmial(@RequestBody UserDot userDot){ try { System.out.println(userDot); return userService.registerEmail(userDot); } catch (Exception e) { e.printStackTrace(); return new AjaxResult(false,"login has failed"); } } }
Service layer:
1. First, judge whether the password is entered and whether the two password inputs are consistent. Before that, judge whether it has been registered asynchronously, so there is no need to judge the mailbox here.
2. Save the registered mailbox and password to the database. The mailbox is also the user name
3. Send the activation email asynchronously (multithreaded). If it is not asynchronous, it will take about 6s to send the email, which greatly reduces the user's experience. After clicking registration, it is stuck for 6s - I thought there was a problem with the network
Note: the @ Async annotation should also be used in the method of sending mail, so that it can be executed asynchronously
4. In the testTemplateMail method of sending template mail, an activation code will be generated and stored on the redis server
@Service public class IUserServiceImpl extends BaseServiceImpl<User> implements IUserService { @Autowired private UserMapper userMapper; @Autowired private SendMailUtil mailUtil; /** * Register via email * @param userDot * @return */ @Override public AjaxResult registerEmail(UserDot userDot){ try { //Judge whether the password is entered if(StringUtils.isBlank(userDot.getPassword())||StringUtils.isBlank(userDot.getConfirmPassword())) return new AjaxResult(false,"Please input a password"); //If the two faces are not equal if(!userDot.getPassword().equals(userDot.getConfirmPassword())) return new AjaxResult(false,"The two passwords are inconsistent"); //Save object User user=new User(); user.setUsername(userDot.getEmail()); user.setEmail(userDot.getEmail()); user.setCreatetime(new Date()); user.setState(0);//Activated after mobile phone verification //Salt value encryption for user password user.setPassword(MD5Utils.encrypByMd5(userDot.getPassword())); //Save user userMapper.saveUser(user); //Send email to newly registered users testTemplateMail(user.getEmail()); return new AjaxResult(false,"The email has been sent to the mailbox. Please complete the activation within 10 minutes!"); } catch (Exception e){ e.printStackTrace(); return new AjaxResult(false,"login has failed!"); } } /** * Send mail * @param receiver addressee */ @Async public void testTemplateMail(String receiver){ //Send mail SimpleDateFormat sdf = new SimpleDateFormat("yyyy year MM month dd day HH Time mm branch ss second"); String subject = "Pet home--User registration"; String emailTemplate = "registerTemplate"; //Get activation code String code = StrUtils.getRandomString(5); //Save the activation code to the redis server //Set the validity period to 10 minutes. The key value is: Action + email. The value value is: verification code RedisUtils.INSTANCE.set("Action:"+receiver,code,10*60); System.out.println("key:"+"Action:"+receiver+" value:"+code); Map<String, Object> dataMap = new HashMap<>(); dataMap.put("email", receiver); dataMap.put("code", code); dataMap.put("createTime", sdf.format(new Date())); try { mailUtil.sendTemplateMail(receiver, subject, emailTemplate, dataMap); System.out.println("Send complete"); } catch (Exception e) { e.printStackTrace(); return; } } }
Mapper layer:
/** * Save user * @param user */ void saveUser(User user);
Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.rk.pethome.user.mapper.UserMapper"> <!--Save user--> <insert id="saveUser" parameterType="user"> insert into t_user(username,email,phone, password, state, createtime) VALUES (#{username},#{email},#{phone},#{password},#{state},#{createtime}) </insert> </mapper>
At this time, the user state attribute is 0, and the user is in an inactive state. We need to go to the mailbox and click the activate button to complete the activation operation before logging in.
4. Realize the mailbox activation function
4.1 click the activation link in the email to jump to the activation page
userActivation(){ let para={"email":this.email,"code":this.code}; this.$http.post("/user/userAction",para).then((res)=> { let {success,msg}=res.data; if(!success)//If activated / / printing fails { this.errorMsg=msg; }else{ //Clear error message this.errorMsg=""; //Complete the activation and jump to the login page location.href="login.html"; } }) },
4.2. Activate the user interface at the back end and modify the state of the operation database to 1
Controller layer:
/** * Log in via email or mobile number * @return */ @PostMapping("/userAction") public AjaxResult activation(@RequestBody HashMap<String,String> para){ try { System.out.println(para.get("code")); String email=para.get("email"); String code = para.get("code"); return userService.activation(email,code); } catch (Exception e) { e.printStackTrace(); return new AjaxResult(false, e.getMessage()); } }
Service layer:
1. Judge whether the entered value is empty
2. Receive the delivered email and the activation code of the user through Action+email. The code is the activation code entered by the user.
3. Judge whether the user name is correctly entered or whether the activation code is expired by obtaining the value from the redis server through Action+email. If it is not empty, compare it with the value entered by the user. Equal indicates that the activation code is correct.
4. Modify the user's state to 1 through email. Indicates that the user has been activated. At this time, remove the activation code on the redis server
/** * User activation * * @param email mailbox * @param code Activation code * @return */ @Override public AjaxResult activation(String email, String code) { //Judge whether the input is empty if(StringUtils.isBlank(email)||StringUtils.isBlank(code)){ return new AjaxResult(false,"Please enter email address and activation code!!"); } //Check whether the activation code is normal //Get the code value from the redis server. If the code value is empty, the activation code is wrong or expired! String s = RedisUtils.INSTANCE.get("Action:" + email);//Activation code obtained from redis server System.out.println("redis The activation code obtained on the server is:"+s); if(s==null) return new AjaxResult(false,"Mailbox error or activation code has expired!!"); //Is the activation code correct if(!code.equals(s))//incorrect { return new AjaxResult(false,"Activation code error!!"); } //Remove from redis server after activation RedisUtils.INSTANCE.del("Action:" + email); //Modifying the user status to 1 indicates that the user has been activated userMapper.updateState(email); return new AjaxResult(); }
Mapper layer:
/** * Activate user * @param email */ void updateState(String email);
Mapper.xml:
<!--Modify user to active status--> <update id="updateState"> update t_user set state=1 where email=#{email} </update>
3. Complete process of mailbox registration and activation
1. Enter the registration page and click Register
2. Enter the mailbox and check the mail
To view the key on the redis server:
To view users registered in the database:
3. Click the link in the email to complete user activation
Incorrect activation code entered:
Enter the correct activation code:
4. Activate successfully, jump to the login interface:
View users in the database
Check the activation code on the redis server: