专栏首页Java探索之路基于Springboot+jpa+thymeleaf+rabbit+SpringBoot mail 的简单项目

基于Springboot+jpa+thymeleaf+rabbit+SpringBoot mail 的简单项目

需求文档

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文件

<?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

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.启动类

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正向工程注解 设置生成后的表名,字段名,主键非空,自增…

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查询用户信息的操作已经为我们封装完成 而稍微复杂的功能,像是多条件查询(根据用户名密码查询用户信息

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层

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 帮助我们跳转到指定的页面

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

/**
 * 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.消息发送类

定义用户登陆,发送信息类

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);
	}
}

定义用户注册时,发送消息的类

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

<!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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>登陆成功</h1>
</body>
</html>

短信系统msg-sys

消息消费者, 接收用户登陆后发送的消息

注意项目的结构,需要编写全局配置文件,配置路由键,交换器,队列,创建启动类

1.pom文件

	<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.全局配置文件

消费者项目需要定义交换器,消息队列,路由键,根据交换器+队列+路由键匹配相关消息

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.启动类

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.消息接收者类

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文件

	<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.修改全局配置文件

消费者项目需要定义交换器,消息队列,路由键,根据交换器+队列+路由键匹配相关消息

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.启动类

/**
 * 短息系统接收者启动器
 * @author 曹海洋
 *
 */
@SpringBootApplication
@EnableRabbit
public class MsgSysApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(MsgSysApplication.class, args);
	}
}

4.接收者类

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

	<!-- 设置status的默认值为0 -->
		<input type="hidden" name="status" value="0"/>

2.修改用于激活账户的controller方法

查到用户,设置status,保存到数据库,并捕获相应的异常

@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, 实现用户的注册时,发送邮箱进行验证的操作?

  1. 邮箱设置->账户->开启服务 打开POP3/SMTP服务(默认关闭), 通过短信验证后会发送给你一个16位的字符串, 可以做qq邮箱密码使用
  1. 添加SpringBoot 的mail模块
		<!--开启QQ邮箱验证 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mail</artifactId>
		</dependency>
  1. 编写配置文件
#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
  1. 在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);
  1. 效果展示

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于VSFTPD技术与KindEditor的简单案例

    1.创建图片上传的service,service实现类,controller(已实现) 2.下载KindEditor,放到静态资源中,并通过script标签指...

    时间静止不是简史
  • Spring全家桶之SpringBoot——初级阶段

    • Spring Boot 设计目的是用来简化新Spring 应用的初始搭建以及开发过程。 • 嵌入的Tomcat,无需部署WAR 文件 • Spring ...

    时间静止不是简史
  • 设计模式之行为型模式

    将一个请求封装成一个对象 ,从而使我们可用不同请求对客户进行参数化 :对请求排队或记录请求日志 ,以及支持可撤销的操作 .也叫: 动作Action模式 ,事务t...

    时间静止不是简史
  • 轻松上手SpringBoot Security + JWT Hello World示例

    在本教程中,我们将开发一个Spring Boot应用程序,该应用程序使用JWT身份验证来保护公开的REST API。在此示例中,我们将使用硬编码的用户和密码进行...

    sanshengshui
  • Redis整合Spring项目搭建实例

    本文介绍了如何使用注解的方式,将Redis缓存整合到你的Spring项目。 首先我们将使用jedis驱动,进而开始配置我们的Gradle。 group 'com...

    CSDN技术头条
  • Spring Boot MongoDB 实例

    节选自《Netkiller Java 手札》 11.12.3. Spring boot mongodb import org.springframework...

    netkiller old
  • Spring boot with Service

    本文节选自《Netkiller java 手札》 5.7. Service 5.7.1. Application @ComponentScan({ "web",...

    netkiller old
  • springboot使用rabbitMQ(带回调)

    配置文件2:RabbitConstants(主要用于用户名、密码等值从配置文件获取,也可以用@Value方式)

    小尘哥
  • Spring Cloud 入门教程2、服务消费者(Ribbon)

    Ribbon是Netflix开源的实现了负载均衡等功能的RPC客户端。 支持HTTP、TCP、UDP协议,且有一定的容错、缓存等机制。

    KenTalk
  • RabbitMQ延迟消息学习

    准备做一个禁言自动解除的功能,立马想到了订单的超时自动解除,刚好最近在看RabbitMQ的实现,于是想用它实现,查询了相关文档发现确实可以实现,动手编写了这篇短...

    河岸飞流

扫码关注云+社区

领取腾讯云代金券