043 用户注册功能03--Redis安装及完成短信发送功能
1.Redis安装
(1)下载地址:https://github.com/MicrosoftArchive/redis/releases/tag/win-3.2.100 ( redis官网: https://redis.io/ )

(2)安装步骤,下一步下一步,有选择框选中即可。



(3)安装完成配置:E:\toolsoftware\redis

设置 redis密码 : requirepass 123456 (我的是 123456)

(4)右击此电脑---》管理


(5)window + R 输入 cmd ===> cd E:\Program Files\Redis ===> redis-cli =====> auth 123456

2.Spring Data Redis
(1)介绍
官网:http://projects.spring.io/spring-data-redis/
Spring Data Redis,是Spring Data 家族的一部分。 对Jedis客户端进行了封装,与spring进行了整合。可以非常方便的来实现redis的配置和操作。
(2)RedisTemplate基本操作
Spring Data Redis 提供了一个工具类:RedisTemplate。里面封装了对于Redis的五种数据结构的各种操作,包括:
redisTemplate.opsForValue() :操作字符串
redisTemplate.opsForHash() :操作hash
redisTemplate.opsForList():操作list
redisTemplate.opsForSet():操作set
redisTemplate.opsForZSet():操作zset
其它一些通用命令,如expire,可以通过redisTemplate.xx()来直接调用
5种结构:
String:等同于java中的,
Map<String,String>list:等同于java中的
Map<String,List<String>>set:等同于java中的
Map<String,Set<String>>sort_set:可排序的set
hash:等同于java中的:`Map<String,Map<String,String>>
(3)StringRedisTemplate
RedisTemplate在创建时,可以指定其泛型类型:
K:代表key 的数据类型
V: 代表value的数据类型
注意:这里的类型不是Redis中存储的数据类型,而是Java中的数据类型,RedisTemplate会自动将Java类型转为Redis支持的数据类型:字符串、字节、二进制等等。
因为大部分情况下,我们都会使用key和value都为String的RedisTemplate,因此Spring就默认提供了这样一个实现:

(4)测试
我们在项目中编写一个测试案例,把课前资料中的redisTest.java导入到项目中

需要在项目中引入Redis启动器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
然后在配置文件中指定Redis地址:
spring:
redis:
host: 127.0.0.1
password: 123456
测试类:
package lucky.leyou.user; import lucky.leyou.LeyouUserApplication;
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.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner; import java.util.Map;
import java.util.concurrent.TimeUnit; @RunWith(SpringRunner.class)
@SpringBootTest(classes = LeyouUserApplication.class)
public class RedisTest { @Autowired
private StringRedisTemplate redisTemplate; @Test
public void testRedis() {
// 存储数据
this.redisTemplate.opsForValue().set("name", "lucky");
// 获取数据
String val = this.redisTemplate.opsForValue().get("name");
System.out.println("name = " + val);
} @Test
public void testRedis2() {
// 存储数据,并指定剩余生命时间,5小时
this.redisTemplate.opsForValue().set("key2", "value2",
5, TimeUnit.HOURS);
} @Test
public void testHash() {
BoundHashOperations<String, Object, Object> hashOps =
this.redisTemplate.boundHashOps("user");
// 操作hash数据
hashOps.put("name", "jack");
hashOps.put("age", "21"); // 获取单个数据
Object name = hashOps.get("name");
System.out.println("name = " + name); // 获取所有数据
Map<Object, Object> map = hashOps.entries();
for (Map.Entry<Object, Object> me : map.entrySet()) {
System.out.println(me.getKey() + " : " + me.getValue());
}
}
}
控制台输出:

3.完成短信发送功能
根据用户输入的手机号,生成随机验证码,长度为6位,纯数字。并且调用短信服务,发送验证码到用户手机。
接口路径:
POST /code
参数说明:

返回结果:
状态码:
204:请求已接收
400:参数有误
500:服务器内部异常
这里的业务逻辑是这样的:
1)我们接收页面发送来的手机号码
2)生成一个随机验证码
3)将验证码保存在服务端
4)发送短信,将验证码发送到用户手机
(1)环境配置
需要三个步骤:
生成随机验证码
将验证码保存到Redis中,用来在注册的时候验证
发送验证码到
leyou-sms-service服务,发送短信
因此,我们需要引入Redis和AMQP:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
添加RabbitMQ和Redis配置:
spring:
redis:
host: 127.0.0.1
password: 123456
rabbitmq:
host: 127.0.0.1
username: guest
password: guest
virtual-host: /
另外还要用到工具类,生成6位随机码,这个我们封装到了leyou-common中,因此需要引入依赖:
<dependency>
<groupId>lucky.leyou.common</groupId>
<artifactId>leyou-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
NumberUtils中有生成随机码的工具方法:
package lucky.leyou.common.utils; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* @author: HuYi.Zhang
* @create: 2018-04-25 09:13
**/
public class NumberUtils { public static boolean isInt(Double num) {
return num.intValue() == num;
} /**
* 判断字符串是否是数值格式
* @param str
* @return
*/
public static boolean isDigit(String str){
if(str == null || str.trim().equals("")){
return false;
}
return str.matches("^\\d+$");
} /**
* 将一个小数精确到指定位数
* @param num
* @param scale
* @return
*/
public static double scale(double num, int scale) {
BigDecimal bd = new BigDecimal(num);
return bd.setScale(scale, RoundingMode.HALF_UP).doubleValue();
} // 从字符串中根据正则表达式寻找,返回找到的数字数组
public static Double[] searchNumber(String value, String regex){
List<Double> doubles = new ArrayList<>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(value);
if(matcher.find()) {
MatchResult result = matcher.toMatchResult();
for (int i = 1; i <= result.groupCount(); i++) {
doubles.add(Double.valueOf(result.group(i)));
}
}
return doubles.toArray(new Double[doubles.size()]);
} /**
* 生成指定位数的随机数字
* @param len
* @return
*/
public static String generateCode(int len){
len = Math.min(len, 8);
int min = Double.valueOf(Math.pow(10, len - 1)).intValue();
int num = new Random().nextInt(Double.valueOf(Math.pow(10, len + 1)).intValue() - 1) + min;
return String.valueOf(num).substring(0,len);
}
}
(2)controller
在leyou-user-service工程中的UserController添加方法:
/**
* 发送手机验证码
* @param phone
* @return
*/
@PostMapping("code")
public ResponseEntity<Void> sendVerifyCode(String phone) {
Boolean boo = this.userService.sendVerifyCode(phone);
if (boo == null || !boo) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<>(HttpStatus.CREATED);
}
(3)service
在UserService中添加代码:
package lucky.leyou.user.service; import lucky.leyou.common.utils.NumberUtils;
import lucky.leyou.user.domain.User;
import lucky.leyou.user.mapper.UserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit; @Service
public class UserService {
@Autowired
private UserMapper userMapper; @Autowired
private StringRedisTemplate redisTemplate; @Autowired
private AmqpTemplate amqpTemplate; static final String KEY_PREFIX = "user:code:phone:"; static final Logger logger = LoggerFactory.getLogger(UserService.class); /**
* 实现用户数据的校验,主要包括对:手机号、用户名的唯一性校验。
* @param data 占位符参数
* @param type
* @return
*/
public Boolean checkUser(String data, Integer type) {
User record = new User();
switch (type) {
case 1:
record.setUsername(data);
break;
case 2:
record.setPhone(data);
break;
default:
return null;
}
return this.userMapper.selectCount(record) == 0;
} /**
* 给指定的手机号发送验证码
* @param phone 待发送验证码的手机号
* @return
*/
public Boolean sendVerifyCode(String phone) {
// 生成验证码
String code = NumberUtils.generateCode(6);
try {
// 发送短信
Map<String, String> msg = new HashMap<>();
msg.put("phone", phone);
msg.put("code", code);
//给rabbitmq的消息队列发送消息
this.amqpTemplate.convertAndSend("leyou.sms.exchange", "sms.verify.code", msg);
// 将code存入redis
this.redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 5, TimeUnit.MINUTES);
return true;
} catch (Exception e) {
logger.error("发送短信失败。phone:{}, code:{}", phone, code);
return false;
}
}
}
注意:要设置短信验证码在Redis的缓存时间为5分钟
(4)测试
http://api.leyou.com/api/user/code?phone=17826828544

redis中查询缓存数据:

043 用户注册功能03--Redis安装及完成短信发送功能的更多相关文章
- day80:luffy:短信sdk接入&点击获取验证码&注册功能的实现&Celery实现短信发送功能
目录 1.短信sdk接入 2.前端点击获取验证码效果 3.注册后端接口实现 4.注册-前端 5.Celery 6.Celery完成短信发送功能 1.短信sdk接入 1.准备工作 1.下载云通讯相关的文 ...
- Swift - 短信发送功能的实现
使用MessageUI.framework框架可以实现短信发送功能,步骤如下: (1)首先判断设备是否有发送短信功能 (2)如果设备允许发送短信,创建一个MFMessageComposeViewCon ...
- 【SSH网上商城项目实战26】完成订单支付后的短信发送功能
转自: https://blog.csdn.net/eson_15/article/details/51475431 上一节我们使用了Java mail完成了给买家发送邮件的功能,还遗留一个功能,就 ...
- 微信开发之移动手机WEB页面(HTML5)Javascript实现一键拨号及短信发送功能
在做一个微信的微网站中的一个便民服务电话功能的应用,用到移动web页面中列出的电话号码,点击需要实现调用通讯录,网页一键拨号的拨打电话功能. 如果需要在移动浏览器中实现拨打电话,发送email,美国服 ...
- [HTML] 微信开发之移动手机WEB页面(HTML5)Javascript实现一键拨号及短信发送功能
在做一个微信的微网站中的一个便民服务电话功能的应用,用到移动web页面中列出的电话号码,点击需要实现调用通讯录,网页一键拨号的拨打电话功能. 如果需要在移动浏览器中实现拨打电话,发送email,美国服 ...
- Laravel实现大型商城网站之用户注册短信发送项目实战功能开发
确定短信运营商 我这里采用的云片,不过大家使用其它的也可以. 首先自己注册一个帐号,然后找到这个 点击开始接入,完成新手引导过程. 第二部的签名和模板必须填写,类似我下面填写的这样 值得注意的是这个模 ...
- PHP控制阿里云短信API接口实现短信群发功能
阿里云短信支持先使用后支付的原则,价格为4分半1条. 通过SDK可以与网站功能的绑定,实现响应的短信发送功能 现已统一合并升级为:消息服务. 消息服务 阿里云消息服务(Message Service, ...
- Android Studio精彩案例(五)《JSMS短信验证码功能实现》
转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 很多应用刚打开的时候,让我们输入手机号,通过短信验证码来登录该应用.那么,这个场景是怎么实现的呢?其实是很多开放平台提供了短信验证功能 ...
- 利用WeX5给手机APP增加短信验证码功能
帖子来源:http://bbs.wex5.com/thread-70908-1-1.html 遇到一个手机APP项目客户要求注册到APP上的用户手机号必须是真实的通过X5平台整合短信发送平台接口完成了 ...
随机推荐
- 递归---Day29
递归的概述 递归:指在当前方法内自己调用自己的方式叫做递归 递归的分类: 1.直接递归称为方法自身调用自己. 2.间接递归可以用A方法调用B方法,用B方法调用C方法,用C方法调用A方法. 递归的注意事 ...
- 设计模式之(十四)责任链模式(Chain of Responsibility)
在业务场景中,有很多是需要审批的.审核方式还可能常常发生变化,而责任链模式就是为了解决这种场景的情况的. 责任链模式定义:十多个对象都有机会处理请求,从而避免发送者和接受者之间的耦合关系.讲这些对象连 ...
- vue通过Blob实现下载文件
需求是这样的...... 具体实现,前端拿到后端返回回来的数据,然后通过Blob实现下载,文件内容样式啥的都是后端写的 script代码: 这里的data就是后端返回回来的数据,此方法兼容IE dow ...
- MySql定时备份脚本
最近需要对某服务的数据库数据进行备份,因此参考网上教程完成数据库备份脚本. 因为服务的使用频率较低,因此设置定时任务,在每天的中午以及午夜时分进行备份操作. #!/bin/bash # 设置mysql ...
- MySQL修炼之路二
1. 表字段的操作 1. 语法: alter table 表名 执行动作: 2. 添加字段(add) alter table 表名 add 字段名 数据类型: alter table 表名 add 字 ...
- mysql数据库之事务和隔离级别
事务和并发执行目的: 1.提高吞吐量,资源利用率 2.减少等待时间 连接管理器:接受请求/创建线程/认证用户/建立安全连接 并发控制:任何时候,只要有两个以上的用户试图读写同时一个文件/数据,都会带来 ...
- js语法中一些容易被忽略,但会造成严重后果的细节
一.复杂数据类型-“对象”的地址引用方式,不理解清楚,会出大乱子 复习一下基础概念(老司机略过): JS的数据可以分为简单类型(数字.字符串.布尔值.null和undefined)和 复杂数据类型(对 ...
- 前端之CSS(上)
CSS CSS 简介 ## CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染 ...
- 【Mybatis】拼接表名
- java生成前端验证码+验证「kaptcha」
1.前言 kaptcha是一个非常实用的短信验证码生成工具,通过简单配置即可实现多样化的验证码. 2.引入依赖 <!--第三方验证码--><dependency> < ...