需求文档
1技术架构
Springboot jpa thymeleaf rabbit 紧跟要求, 不需要使用Mybatis, 也不需要使用Eureka!!! 使用RabbitMQ需要安装RabbitMQ的客户端,点击查看第四章安装教程
2功能要求
2.1用户登录 用户登录的时候提交用户名和密码,然后给用户短信提示,用户在什么时间,用哪个IP,进行登录。需要将电话-时间-IP格式的数据保存到队列中 2.2用户注册 用户注册,用户注册后,给用户注册信息进行邮箱的激活,点击哪个url进行账户激活。修改数据库中locked字段的值。需要将Email-时间-URL格式的数据保存到队列中
3参考界面
3.1用户登录
3.2用户注册
4系统架构
说明: p,e为路由key。 用户系统完成登录的时候,将{手机号-时间-IP}保存到队列Phone-queue中,msg-sys系统获得消息打印到控制台(完成用户登录过程短信服务的异步调用,完成用户系统和短信系统的解耦合) 用户系统完成注册的时候,将{email-时间-IP-账户激活url }保存到队列email-sys中,email-sys将消息打印到控制台,使用控制台打印的账户激活的url,在浏览器向user-sys系统发送请求,修改user表中locked字段的值。(完成用户注册过程邮件服务的异步调用,完成用户系统和邮件系统的解耦合),修改完成后给用户提示账户激活成功
项目思路
根据系统架构,创建三个项目,用户登陆项目user-sys,短信系统msg-sys,邮件系统mail-sys
用户登陆项目user-sys, 负责用户登陆前后端页面交互, RabbitMQ的消息生产者 短信系统msg-sys, 消息消费者, 接收用户登陆后发送的消息 邮件系统mail-sys ,消息消费者, 接收用户注册消息以及激活账户的消息
在消息生产者那一方,需要定义交换器 ,路由键, 这里使用Direct交换器 在消息消费者那一方,需要定义交换器,消息队列,路由键 他们首先会根据交换器进行粗劣匹配,然后会根据路由键匹配对应的消息队列, 消息消费者则会一直监听消息队列是否有他的消息,如果有就输出
在做项目时, 可以先将用户登陆注册功能实现后, 然后添加RabbitMQ相关配置再创建两个消息消费者
项目搭建
用户登陆项目user-sys
1.pom文件
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>ah.szxy.boot.test</groupId>
<artifactId>EXAM-User-sys</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>EXAM-LoginSystem</name>
<description>project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
</properties>
<dependencies>
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- rabbitmq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- springBoot-jpa 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- DevTools 项目热部署的坐标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
2.全局配置文件application.yml
代码语言:javascript复制spring: #配置应用名,数据库连接参数
application:
name: login-system
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/exam?useSSL=false&serverTimezone=UTC
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
#开启正向工程
jpa:
hibernate:
ddl-auto: update
show-sql: true #运行时,打印sql语句
main:
allow-bean-definition-overriding: true
rabbitmq:
host: 192.168.179.136
port: 5672
password: mquser
username: mquser
server: #配置端口号
port: 8888
#设置交换器的名称
mq.config.exchange: user.direct
# 短信系统路由键
mq.config.queue.message.routing.key: p
# 邮件系统 路由键
mq.config.queue.email.routing.key: e
3.启动类
代码语言:javascript复制package ah.szxy;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableRabbit
public class ExamLoginSystemApplication {
public static void main(String[] args) {
SpringApplication.run(ExamLoginSystemApplication.class, args);
}
}
4.实体类
开启正向工程: 根据编写的实体类自动生成数据库表 并进行简单的表单校验 @NotBlank,@Email,@Length是表单校验注解,其他是Hibernate正向工程注解 设置生成后的表名,字段名,主键非空,自增…
代码语言:javascript复制package ah.szxy.pojo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
@Entity
@Table(name="t_users")
public class Users {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="userid")
private Integer userid;
@NotBlank(message="用户名需要长度为5-10位") //非空校验
@Length(min=5,max=10)
@Column(name="username")
private String username;
@NotBlank(message="密码需要长度为6-10位") //密码非空校验
@Length(min=6,max=10)
@Column(name="password")
private String password;
@Column(name="phone")
private String phone;
@Email
@Column(name="email")
private String email;
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
5.dao层
因为使用了SpringData jpa 像是简单的插入,根据用户id查询用户信息的操作已经为我们封装完成 而稍微复杂的功能,像是多条件查询(根据用户名密码查询用户信息
代码语言:javascript复制package ah.szxy.mapper;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import ah.szxy.pojo.Users;
/**
* 参数一T :当前需要映射的实体
* 参数二ID :当前映射的实体中的OID 的类型
*
*/
public interface UsersDao extends JpaRepository<Users, Integer> ,JpaSpecificationExecutor<Users>{
Users findByUsernameAndPassword(String username,String password);
}
6.service层
代码语言:javascript复制package ah.szxy.service;
import org.springframework.web.bind.annotation.RequestParam;
import ah.szxy.pojo.Users;
public interface UsersService {
void insertUser(Users users);
Users login( String username, String password);
Users findUserById(Integer id);
}
package ah.szxy.service.impl;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ah.szxy.mapper.UsersDao;
import ah.szxy.pojo.Users;
import ah.szxy.service.UsersService;
@Service
public class UsersServiceImpl implements UsersService{
@Autowired
private UsersDao userDao;
@Override
public void insertUser(Users users) {
this.userDao.save(users);
}
@Override
public Users login(String username, String password) {
return this.userDao.findByUsernameAndPassword(username, password);
}
@Override
public Users findUserById(Integer id) {
Users user = this.userDao.findById(id).get();
return user;
}
}
7.controller
PageController 帮助我们跳转到指定的页面
代码语言:javascript复制package ah.szxy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class PageController {
@RequestMapping("/{page}")
public String showPage(@PathVariable String page) {
return page;
}
}
业务实现的controller 其实可以将具体业务提到接口实现类,因为方便故将其放到了controller
代码语言:javascript复制/**
* http://localhost:8888/addUser 用户注册
* http://localhost:8888/login 用户登陆
* @author chy
*
*/
@Controller
public class UsersController {
@Autowired
private UsersService usersService;
@Autowired
private LoginInfoSender loginInfoSender;
@Autowired
private RegisterInfoSender registerInfoSender;
/**
* 用户注册跳转的方法
* 因为需要表单校验,所以即使配置了页面跳转的controller也不能直接访问
* @param users
* @return
*/
@RequestMapping("/addUser")
public String addUser(Users users) {
return "reg";
}
/**
* 用户注册
* @param users
* @param result
* @return
*/
@RequestMapping("/save")
public String saveUser(@Valid Users users, BindingResult result) {
if (result.hasErrors()) {
return "reg";
}
this.usersService.insertUser(users);
System.out.println("注册成功!用户信息为: " users);
//将Email-时间-URL格式的数据保存到队列中
String email=users.getEmail();
Date date=new Date();
this.registerInfoSender.send(email "---" date);
//发送激活信息
String url="http://localhost:8888/active/" users.getUserid();
this.registerInfoSender.send("请双击此链接进行激活 : " url);
return "login";
}
/**
* 用户登陆
* @param users
* @param result
* @return
*/
@RequestMapping("/userlogin")
public String login(String username,String password,HttpServletRequest request) {
Users user = this.usersService.login(username, password);
if (user!=null) {
System.out.println("登陆成功!用户信息为: " user);
//电话-时间-IP格式的数据保存到队列中
String phone=user.getPhone();
Date date=new Date();
String ip = request.getRemoteHost();
this.loginInfoSender.send(phone date ip);
return "loginSuccess";
}
return "login";
}
@RequestMapping("/active/{id}")
@ResponseBody
public String activeUser(@PathVariable Integer id) {
try {
Users user = this.usersService.findUserById(id);
Integer userid=user.getUserid();
System.out.println("激活系统" user id);
if (userid==id) {
return "激活成功";
}else {
return "激活失败,验证码不正确,请重新输入";
}
} catch (Exception e) {
e.printStackTrace();
}
return "激活失败";
}
}
8.消息发送类
定义用户登陆,发送信息类
代码语言:javascript复制package ah.szxy.sender;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 用户登陆后,向Phone-queue队列发送消息
*
* @author chy
*
*/
@Component
public class LoginInfoSender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交换器名称
@Value("${mq.config.exchange}")
private String exchange;
//routingkey 路由键
@Value("${mq.config.queue.message.routing.key}")
private String routingkey;
/*
* 发送消息的方法
*/
public void send(String msg) {
/**
* 向消息队列发送消息
* 参数一:交换器的名称
* 参数二:路由键;
* 参数三:消息
*/
this.rabbitAmqpTemplate.convertAndSend(this.exchange,this.routingkey, msg);
}
}
定义用户注册时,发送消息的类
代码语言:javascript复制package ah.szxy.sender;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 用户注册后,发送消息到email-queue队列
* @author chy
*
*/
@Component
public class RegisterInfoSender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交换器名称
@Value("${mq.config.exchange}")
private String exchange;
//routingkey 路由键
@Value("${mq.config.queue.email.routing.key}")
private String routingkey;
/*
* 发送消息的方法
*/
public void send(String msg) {
/**
* 向消息队列发送消息
* 参数一:交换器的名称
* 参数二:路由键;
* 参数三:消息
*/
this.rabbitAmqpTemplate.convertAndSend(this.exchange,this.routingkey, msg);
}
}
9.前端页面
注册页面reg.html
这里进行了表单校验,通过th:errors
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>用户注册</h1>
<!-- th:errors 会获取响应的数据 .有,会将数据取出,没有会报异常 -->
<form th:action="@{/save}" method="post">
用户姓名:<input type="text" name="username" />
<font color="red" th:errors="${users.username}"></font><br />
用户密码:<input type="password" name="password" />
<font color="red" th:errors="${users.password}"></font><br />
确认密码:<input type="password" name="" />
<font color="red" th:errors="${users.password}"></font><br />
用户邮箱:<input type="text" name="email" />
<font color="red" th:errors="${users.email}"></font><br />
用户电话:<input type="text" name="phone" />
<font color="red" th:errors="${users.phone}"></font><br />
<input type="submit" value="添加" />
</form>
</body>
</html>
登陆页面login.html
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>请登录</h1>
<form th:action="@{/userlogin}" method="post">
用户姓名:<input type="text" name="username" /><br>
用户密码:<input type="password" name="password" /><br>
<input type="submit" value="登陆">
<form>
</form>
</body>
</html>
登陆成功页面 loginSuccess.html
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>登陆成功</h1>
</body>
</html>
短信系统msg-sys
消息消费者, 接收用户登陆后发送的消息
注意项目的结构,需要编写全局配置文件,配置路由键,交换器,队列,创建启动类
1.pom文件
代码语言:javascript复制 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<!-- 解决第pom文件一行报错的问题 -->
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
</properties>
<dependencies>
<!-- springBoot 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- rabbitmq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
2.全局配置文件
消费者项目需要定义交换器,消息队列,路由键,根据交换器 队列 路由键匹配相关消息
代码语言:javascript复制spring:
application:
name: msg-sys
rabbitmq:
host: 192.168.179.136
password: mquser
username: mquser
port: 5672
server:
port: 8081
#设置交换器的名称
mq.config.exchange: user.direct
#短信 队列名称
mq.config.queue.phone: Phone-queue
# 短信系统路由键
mq.config.queue.message.routing.key: p
3.启动类
代码语言:javascript复制package ah.szxy.msg.sys;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 邮件系统接收者启动器
* @author chy
*
*/
@SpringBootApplication
@EnableRabbit
public class MsgSysApplication {
public static void main(String[] args) {
SpringApplication.run(MsgSysApplication.class, args);
}
}
4.消息接收者类
代码语言:javascript复制package ah.szxy.msg.sys.receiver;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 消息接收者
*
* @RabbitListener bindings:绑定队列
* @QueueBinding value:绑定队列的名称 exchange:配置交换器
* @Queue value:配置队列名称 autoDelete:是否是一个可删除的临时队列
* @Exchange value:为交换器起个名称 type:指定具体的交换器类型
* @author chy
*
*/
@Component
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value ="${mq.config.queue.phone}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.DIRECT),
key = "${mq.config.queue.message.routing.key}"))
public class LoginReceiver {
/**
* 接收消息的方法。采用消息队列监听机制
*
* @param msg
*/
@RabbitHandler
public void process(String msg) {
System.out.println("有用户登陆成功,登陆信息为 : " msg);
}
}
邮件系统mail-sys
消息消费者, 接收用户注册消息以及激活账户的消息
注意项目的结构,需要编写全局配置文件,配置路由键,交换器,队列,创建启动类
1.pom文件
代码语言:javascript复制 <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
<!-- 解决第pom文件一行报错的问题 -->
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
</properties>
<dependencies>
<!-- springBoot 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- rabbitmq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
2.修改全局配置文件
消费者项目需要定义交换器,消息队列,路由键,根据交换器 队列 路由键匹配相关消息
代码语言:javascript复制spring:
application:
name: email-sys
rabbitmq:
host: 192.168.179.136
password: mquser
username: mquser
port: 5672
server:
port: 8082
#设置交换器的名称
mq.config.exchange: user.direct
#error 队列名称
mq.config.queue.email: Email-queue
# 短信系统路由键
mq.config.queue.email.routing.key: e
3.启动类
代码语言:javascript复制/**
* 短息系统接收者启动器
* @author 曹海洋
*
*/
@SpringBootApplication
@EnableRabbit
public class MsgSysApplication {
public static void main(String[] args) {
SpringApplication.run(MsgSysApplication.class, args);
}
}
4.接收者类
代码语言:javascript复制package ah.szxy.msg.sys.receiver;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 消息接收者
*
* @RabbitListener bindings:绑定队列
* @QueueBinding value:绑定队列的名称 exchange:配置交换器
* @Queue value:配置队列名称 autoDelete:是否是一个可删除的临时队列
* @Exchange value:为交换器起个名称 type:指定具体的交换器类型
* @author chy
*
*/
@Component
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.email}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.DIRECT),
key = "${mq.config.queue.email.routing.key}"))
public class RegisterReceiver {
/**
* 接收消息的方法。采用消息队列监听机制
*
* @param msg
*/
@RabbitHandler
public void process(String msg) {
System.out.println("有用户注册成功,注册信息为 : " msg);
}
}
效果演示
1.注册时的表单校验
2.注册成功, 邮件系统接收到激活信息
3.访问激活连接
4,使用创建好的账户进行登陆,登陆成功后,短信系统收到消息
短信系统控制台
在RabbitMQ可以找到图形化界面
该队列下的两个消息队列和对应的路由键
后续思路
在之前的编写时未考虑状态激活逻辑,因此可以进行如下思考: 用户注册成功后,需要将账号的激活状态设置为1,然后可以登录(根据用户名密码匹配到用户信息后, 获取status值,进行比对,如果不为1跳转到登陆失败页面或重定向登陆页面)
编写代码时 可以在用户表生成时,设置一个状态(status) , 为0代表注册不成功(被锁定), 为1代表激活成功(解除锁定) 在用户激活的controller方法中, 首先查询用户信息(已实现), 然后将设置status设置为1(调用save方法),代表已激活
步骤
1.实体类添加相关属性 ,设置默认值
如何设置Hibernate字段默认值为0?
方式一
在Hibernate正向工程的实体类中设置默认值注解@ColumnDefault("0")
方式二 实体类上添加该属性不设置其他,注册时,在表单中添加一个隐藏域 ,设置值为0
代码语言:javascript复制 <!-- 设置status的默认值为0 -->
<input type="hidden" name="status" value="0"/>
2.修改用于激活账户的controller方法
查到用户,设置status,保存到数据库,并捕获相应的异常
代码语言:javascript复制@RequestMapping("/active/{id}")
@ResponseBody
public String activeUser(@PathVariable Integer id) {
try {
Users user = this.usersService.findUserById(id);
Integer userid=user.getUserid();
System.out.println("激活系统" user id);
if (userid==id) {
try {
user.setStatus(1);
this.usersService.insertUser(user);
return "激活成功";
} catch (Exception e) {
e.printStackTrace();
}
return "系统内部出现错误";
}else {
return "激活失败,验证码不正确,请重新输入";
}
} catch (Exception e) {
e.printStackTrace();
}
return "激活失败";
}
Hibernate正向工程没有自带更新操作, 所以我们需要先根据id查到这个对象,然后修改他,通过自带的Save方法保存, 在这里Save方法被封装在userService的insert方法中,所以只需调用即可使用
3.效果展示
启动三个项目,注册后status为0代表锁定
访问邮件系统接收的激活信息后,可以看到status变为1啦,大功告成 (*^▽^*)
整合SpringBoot的mail模块
如何整合SpringBoot 的mail, 实现用户的注册时,发送邮箱进行验证的操作?
- 邮箱设置->账户->开启服务 打开POP3/SMTP服务(默认关闭), 通过短信验证后会发送给你一个16位的字符串, 可以做qq邮箱密码使用
- 添加SpringBoot 的mail模块
<!--开启QQ邮箱验证 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
- 编写配置文件
#qq邮箱的规则
spring.mail.host=smtp.qq.com
spring.mail.username=123456@qq.com
spring.mail.password=fimkehjopzmahcdd #第三方生成的16位字符串token
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
- 在controller中添加如下代码
@Autowired
private JavaMailSender mailSender; //注入java中用于发送邮件的API
//发送激活信息
String url="http://localhost:8888/active/" users.getUserid();
//this.registerInfoSender.send("请双击此链接进行激活 : " url);
/**
* 向qq邮箱发送信息
*/
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("123456@qq.com");//信息由谁发送
message.setTo(users.getEmail());//信息发送给谁
message.setSubject("主人主人!!你有新邮件啦~");//设置邮件的主题
message.setText(url);//设置邮件的内容
mailSender.send(message);
- 效果展示