Spring Boot 整合Spring Data以及rabbitmq,thymeleaf,向qq邮箱发送信息
首先得将自己的qq开启qq邮箱的POP3/SMTP服务
说明:
p,e为路由key。
用户系统完成登录的时候,将{手机号-时间-IP}保存到队列Phone-queue中,msg-sys系统获得消息打印到控制台(完成用户登录过程短信服务的异步调用,完成用户系统和短信系统的解耦合)
用户系统完成注册的时候,将{email-时间-IP-账户激活url }保存到队列email-sys中,email-sys将消息打印到控制台,使用控制台打印的账户激活的url,在浏览器向user-sys系统发送请求,修改user表中locked字段的值。(完成用户注册过程邮件服务的异步调用,完成用户系统和邮件系统的解耦合),修改完成后给用户提示账户激活成功
用户登录
用户登录的时候提交用户名和密码,然后给用户短信提示,用户在什么时间,用哪个IP,进行登录。需要将电话-时间-IP格式的数据保存到队列中
用户注册
用户注册,用户注册后,给用户注册信息进行邮箱的激活,点击哪个url进行账户激活。修改数据库中locked字段的值。需要将Email-时间-URL格式的数据保存到队列中
当我们点击注册的时候,会向消息队列发送注册信息,以及向qq邮箱发送文件激活的url
然后看pom文件
<?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.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>spring-boot-jpa-dlzc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-jpa-dlzc</name>
<description>spring-boot-jpa-dlzc</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--开启QQ邮箱验证-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<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>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
由于此项目用到了消息队列
因此注意项目奖结构
消息的发送者 spring-boot-jpa-dlzc
application.properties配置文件
#Mysql数据源配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sys?characterEncoding=UTF8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
#JPA相关配置
#项目启动生成数据库
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
server.port=8081
spring.rabbitmq.host=192.168.181.134
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=111111
#设置交换器的名称
mq.config.exchange=log.direct
#设置短信的路由键
mq.config.queue.message.routing.key=log.message.routing.key
#设置邮件的路由键
mq.config.queue.email.routing.key=log.email.routing.key
#qq邮箱的规则
spring.mail.host=smtp.qq.com
spring.mail.username=设置申请邮箱的账号
spring.mail.password=邮箱的验证码
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
实体类
locked字段是为了激活账号使用的,给予默认值是0,注册成但是未激活的时候,此时locked值是0,点击激活之后locked值修改成1,在我们登录的时候带着uname和pwd以及locked的值为1三个条件去判断,如果有值说明账户激活成功,查询没有则返回用户,账户未激活信息提示
package com.bjsxt.pojo;
import lombok.Data;
import org.hibernate.annotations.ColumnDefault;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "users")
@Data
public class Users implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "uid")
private int uid;
@Column(name = "uname")
private String uname;
@Column(name = "pwd")
private String pwd;
@Column(name = "email")
private String email;
@Column(name = "phone")
private String phone;
@Column(name = "locked")
@ColumnDefault(value = "0")
private int locked;
public Users() {
}
public Users(String uname, String pwd, String email, String phone, int locked) {
this.uname = uname;
this.pwd = pwd;
this.email = email;
this.phone = phone;
this.locked = locked;
}
}
消息发送实现类
com.bjsxt.send.LoginSender
package com.bjsxt.send;
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;
/***
* 消息的发送者
*/
@Component
public class LoginSender {
@Autowired
private AmqpTemplate amqpTemplate;
@Value("${mq.config.exchange}")
private String exchange;
@Value("${mq.config.queue.message.routing.key}")
private String routingkey;
/**
* 发送消息的方法
* @param msg
*/
public void sendMsg(String msg){
/*向消息队列发送消息*/
/*
* 参数一:队列的名称
* 参数二:发送的消息
* */
amqpTemplate.convertAndSend(exchange,routingkey,msg);
}
}
com.bjsxt.send.RegSender
package com.bjsxt.send;
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;
/***
* 消息的发送者
*/
@Component
public class RegSender {
@Autowired
private AmqpTemplate amqpTemplate;
@Value("${mq.config.exchange}")
private String exchange;
@Value("${mq.config.queue.email.routing.key}")
private String routingkey;
/**
* 发送消息的方法
* @param msg
*/
public void sendMsg(String msg){
/*向消息队列发送消息*/
/*
* 参数一:队列的名称
* 参数二:发送的消息
* */
amqpTemplate.convertAndSend(exchange,routingkey,msg);
}
}
dao层
com.bjsxt.dao.UserDao
package com.bjsxt.dao;
import com.bjsxt.pojo.Users;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
public interface UserDao extends JpaRepository<Users,Integer>, JpaSpecificationExecutor<Users> {
/**
* 登录操作
* @param uname
* @param pwd
* @return
*/
@Query(value = "select * from users where uname=? and pwd =? and locked=1",nativeQuery = true)
Users findUser(String uname,String pwd);
/**
* 激活操作
* @param uid
*/
@Modifying
@Transactional
@Query(value = "update users set locked=1 where uid=?",nativeQuery = true)
void updateUser(int uid);
/**
* 激活操作
* @param uname
* @param pwd
*/
@Modifying
@Transactional
@Query(value = "update users set locked=1 where uname=? and pwd =?",nativeQuery = true)
void updateUserlocked(String uname,String pwd);
}
service层
com.bjsxt.service.UserService(接口)
package com.bjsxt.service;
import com.bjsxt.pojo.Users;
public interface UserService {
/**
* 添加用户
* @param users
*/
void addUser(Users users);
/**
* 处理登录请求
* @param uname
* @param pwd
* @return
*/
Users findUser(String uname,String pwd);
/***
* 处理用户激活
* @param uid
* @return
*/
void updateUserLock(int uid);
/**
* 处理用户激活
* @param uname
* @param pwd
*/
void updateLock(String uname,String pwd);
}
com.bjsxt.service.impl.UserServiceImpl接口实现类
package com.bjsxt.service.impl;
import com.bjsxt.dao.UserDao;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
/**
* 添加用户操作
* @param users
*/
@Override
public void addUser(Users users) {
userDao.save(users);
}
/**
* 处理登录操作
* @param uname
* @param pwd
* @return
*/
@Override
public Users findUser(String uname, String pwd) {
return userDao.findUser(uname,pwd);
}
/**
* 处理用户激活操作
* @param uid
*/
@Override
public void updateUserLock(int uid) {
userDao.updateUser(uid);
}
/**
* 处理用户激活
* @param uname
* @param pwd
*/
@Override
public void updateLock(String uname,String pwd) {
userDao.updateUserlocked(uname,pwd);
}
}
控制层
com.bjsxt.controller.PageController(页面跳转)
package com.bjsxt.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class PageController {
/***
* 展示页面
* @return
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
com.bjsxt.controller.UserController用户操作处理
package com.bjsxt.controller;
import com.bjsxt.pojo.Users;
import com.bjsxt.send.LoginSender;
import com.bjsxt.send.RegSender;
import com.bjsxt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class UserController {
@Autowired
private JavaMailSender mailSender;
@Autowired
private UserService us;
@Autowired
private RegSender regSender;
@Autowired
private LoginSender loginSender;
@RequestMapping("/save")
public String addUser(Users users){
us.addUser(users);
//将Email-时间-URL格式的数据保存到队列中
String email = users.getEmail();
Date now =new Date();
SimpleDateFormat spdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
String date = spdf.format(now);
String url="http://192.168.41.24:8081/locked/"+users.getUid();
regSender.sendMsg("邮箱:"+email+"\t时间:"+date+"\turl:"+url);
/**
* 向qq邮箱发送信息
*/
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("1252639547@qq.com");//信息由谁发送
message.setTo(users.getEmail());//信息发送给谁
message.setSubject("主人主人!!你有新邮件啦~");//设置邮件的主题
message.setText(url);//设置邮件的内容
mailSender.send(message);
return "login";
}
@RequestMapping("/loginuser")
public String login(String uname, String pwd, HttpServletRequest request){
Users user = us.findUser(uname, pwd);
if (user!=null){
//电话-时间-IP格式的数据保存到队列中
String phone = user.getPhone();
Date now =new Date();
SimpleDateFormat spdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
String date = spdf.format(now);
String ip = request.getRemoteHost();
loginSender.sendMsg("电话:"+phone+"\t时间:"+date+"\tIP:"+ip);
return "success";
}else {
request.setAttribute("uname",uname);
request.setAttribute("pwd",pwd);
return "cuowu";
}
}
/**
* 处理用户激活
* @param uid
* @return
*/
@RequestMapping("/locked/{uid}")
public String bindLock(@PathVariable int uid){
us.updateUserLock(uid);
return "success1";
}
/**
* 处理用户激活
* @param uname
* @param pwd
* @return
*/
@RequestMapping("/lock/{uname}/{pwd}")
public String Locked(@PathVariable String uname,@PathVariable String pwd){
us.updateLock(uname,pwd);
return "success1";
}
}
前端的页面分步
注册界面
templates/reg.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>注册</title>
</head>
<body>
<h1 style="align-content: center">用户注册</h1>
<form th:action="@{/save}" method="post" style="align-content: center">
<p>
用户名:<input type="text" name="uname">
</p>
<p>
密码:<input type="password" name="pwd">
</p>
<p>
确认密码:<input type="password">
</p>
<p>
邮箱:<input type="email" name="email">
</p>
<p>
电话号码:<input type="number" name="phone">
</p>
<p>
<input type="submit" value="注册">
</p>
</form>
</body>
</html>
登录界面
templates/login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<form method="post" th:action="@{/loginuser}">
<p>
用户名:<input type="text" name="uname">
</p>
<p>
密码:<input type="password" name="pwd">
</p>
<p>
<input type="submit" value="登录"> <a href="reg.html">戳我去注册</a>
</p>
</form>
</body>
</html>
当你注册成功后,但是没有激活直接登录,失败界面
templates/cuowu.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>主页面</title>
</head>
<body>
<h1>亲,你还未激活,请点击激活后登录</h1>
<table border="1">
<tr>
<th>用户名</th>
<th>密码</th>
<th>操作</th>
</tr>
<tr>
<th th:text="${uname}"></th>
<th th:text="${pwd}"></th>
<th><a th:href="@{/lock/}+${uname}+@{/}+${pwd}">激活</a></th>
</tr>
</table>
</body>
</html>
用户激活成功页面
templates/success1.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>激活页面</title>
</head>
<body>
<h1><a th:href="@{/login.html}">用户激活成功,戳我去登录</a></h1>
</body>
</html>
登录成功页面
templates/success.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>主页面</title>
</head>
<body>
<h1>登录成功</h1>
</body>
</html>
消息接受者 spring-boot-jpa-zcdl-consumer
pom文件
<?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.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>spring-boot-jpa-zcdl-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-jpa-zcdl-consumer</name>
<description>spring-boot-jpa-zcdl-consumer</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties配置文件
server.port=8082
spring.rabbitmq.host=192.168.181.134
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=111111
#设置交换器的名称
mq.config.exchange=log.direct
#设置短信队列名称
mq.config.queue.message=log.message
#设置短信的路由键
mq.config.queue.message.routing.key=log.message.routing.key
#设置邮件队列名称
mq.config.queue.email=log.email
#设置邮件的路由键
mq.config.queue.email.routing.key=log.email.routing.key
接收消息
com.bjsxt.receiver.EmailReceiver
package com.bjsxt.receiver;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
@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 EmailReceiver {
/**
* 接收消息的方法
* 采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("邮件消息:"+msg);
}
}
com.bjsxt.receiver.MessageReceiver
package com.bjsxt.receiver;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
@Component
@RabbitListener(
bindings = @QueueBinding(
value =@Queue(value = "${mq.config.queue.message}",autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}",type = ExchangeTypes.DIRECT),
key = "${mq.config.queue.message.routing.key}"
)
)
public class MessageReceiver {
/**
* 接收消息的方法
* 采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("短信消息:"+msg);
}
}
Spring Boot 整合Spring Data以及rabbitmq,thymeleaf,向qq邮箱发送信息的更多相关文章
- Spring Boot 整合Spring Data JPA
Spring Boot整合Spring Data JPA 1)加入依赖 <dependency> <groupId>org.springframework.boot</g ...
- Spring boot 整合spring Data JPA+Spring Security+Thymeleaf框架(上)
近期上班太忙所以耽搁了给大家分享实战springboot 框架的使用. 以下是spring boot 整合多个框架的使用. 首先是准备工作要做好. 第一 导入框架所需的包,我们用的事maven 进行 ...
- Spring Boot整合Spring Security自定义登录实战
本文主要介绍在Spring Boot中整合Spring Security,对于Spring Boot配置及使用不做过多介绍,还不了解的同学可以先学习下Spring Boot. 本demo所用Sprin ...
- Spring Boot整合Spring Security总结
一.创建Spring Boot项目 引入Thymeleaf和Web模块以及Spring Security模块方便进行测试,先在pom文件中将 spring-boot-starter-security ...
- Spring Boot整合Spring Security
Spring Boot对于该家族的框架支持良好,但是当中本人作为小白配置还是有一点点的小问题,这里分享一下.这个项目是使用之前发布的Spring Boot会员管理系统重新改装,将之前filter登录验 ...
- Spring Boot整合Spring Batch
引言 Spring Batch是处理大量数据操作的一个框架,主要用来读取大量数据,然后进行一定的处理后输出指定的形式.比如我们可以将csv文件中的数据(数据量几百万甚至几千万都是没问题的)批处理插入保 ...
- Spring Boot整合Spring Session实战
传统java web应用session都是由应用服务器(如tomcat)保存在内存中,这对应但节点应用来说没问题:但对于应用集群来说会造成各节点之间的session无法共享,一个节点挂掉后,其他节点接 ...
- Spring Boot 整合 Spring Security,用户登录慢
场景 Spring Boot + Spring Security搭建一个Web项目. 临时用了inMemoryAuthentication. @EnableWebSecurity public cla ...
- spring boot整合spring Data JPA和freemarker
1.spring Data JPA简介 是一个替代hibernate的一个作用于数据库的框架. 2.整合 1.导入依赖 <dependency> <groupId>org.sp ...
随机推荐
- day5-列表专区
list 列表.类li = [1, 12, 9, "age", ["88", ["19", 10], "方法"], &q ...
- day1-习题
# 1.使用while循环输入 1 2 3 4 5 6 8 9 10 count = 1 while count<11 : #使用while语句循环输入123...10 if count == ...
- linux 设置固定ip和dns
目录 1. centos 1.1 ifconfig 查看网卡名称 1.2 设置固定ip和dns 1.3 重启网络 2. ubuntu 2.1 ifconfig 查看网卡名称 2.2 设置固定ip和dn ...
- pip的简单用法
pip的用法: 其实跟linux的yum很像,它可以帮我们安装python所需要的环境包,并且可以包解决依赖关系 eg: 列出已安装的包 pip list 安装要安装的包 pip install xx ...
- 初识web API接口及Restful接口规范
一.web API接口 什么是web API接口?: 明确了请求方式,提供对应后台所需参数,请求url链接可以得到后台的响应数据 url : 返回数据的url https://api.map.baid ...
- 用这个库 3 分钟实现让你满意的表格功能:Bootstrap-Table
本文作者:HelloGitHub-kalifun 这是 HelloGitHub 推出的<讲解开源项目>系列,今天给大家推荐一个基于 Bootstrap 和 jQuery 的表格插件:Boo ...
- sparkSQL 简介
一.Spark SQL的特点 1.支持多种数据源:Hive.RDD.Parquet.JSON.JDBC等.2.多种性能优化技术:in-memory columnar storage.byte-code ...
- java编程思想第四版第三章要点总结
1. 静态导入 使用import static方式导入一个类的所有方法. 例如: import static net.mindview.util.Print.*; 首先定义了一个Print类,里面有静 ...
- nyoj 125-盗梦空间 (数学ans += temp * 60 * pow(0.05, cnt))
125-盗梦空间 内存限制:64MB 时间限制:3000ms 特判: No 通过数:8 提交数:10 难度:2 题目描述: <盗梦空间>是一部精彩的影片,在这部电影里,Cobb等人可以进入 ...
- JS三座大山再学习(一、原型和原型链)
原文地址 ## 前言 西瓜君之前学习了JS的基础知识与三座大山,但之后工作中没怎么用,印象不太深刻,这次打算再重学一下,打牢基础.冲鸭~~ 原型模式 JS实现继承的方式是通过原型和原型链实现的,JS中 ...