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平台整合短信发送平台接口完成了 ...
随机推荐
- Java诊断利器Arthas优雅排查生产环境
前言 Arthas 是Alibaba开源的Java诊断工具.在线排查问题,无需重启:动态跟踪Java代码:实时监控JVM状态.对分秒必争的线上异常,Arthas可帮助我们快速诊断相关问题. 下载安装 ...
- Linux yum的配置 , python环境管理, nginx搭建简单学习
Linux yum的配置 , python环境管理, nginx搭建简单学习 一丶配置yum的数据仓库 ### yum 工具, 方便,自行解决软件之间的依赖关系. # 配置yum源仓库 (可以使用,清 ...
- Matlab空对象模式
在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查.Null 对象不是检查空值,而是反应一个不做任何动作的关系.这样的 Null 对象也可以在数据不可用 ...
- C#常用集合类的实现以及基本操作复杂度
List 集合类是顺序线性表,Add操作是O(1)或是O(n)的,由于List的容量是动态扩容的,在未扩容之前,其Add操作是O(1),而在需要扩容的时候,会拷贝已存在的那些元素同时添加新的元素,此时 ...
- c# 导出2007格式的Excel的连接字符串
上次做了个导出excel文件的客户端软件,没有注意到:当打开2007版的excel时提示错误“外部表不是预期的格式”,刚才网上荡了点资料,改了一下连接字符串,问题解决了: 把:string strCo ...
- cc.isChildClassOf 判断两个类的继承关系
使用 cc.isChildClassOf 来判断两个类的继承关系: var Texture = cc.Class(); var Texture2D = cc.Class({ extends: Text ...
- C# 连接数据操作的时候抛异常,连接超时
先说说我的业务.我在发送优惠券的时候,同时给6千多个会员发送优惠券,执行了update 和insert语句,这写语句都是通过字符串拼接而来的.update和insert语句加起来一共是一万多条语句.在 ...
- django2外键,F表达式,Q表达式
一对多 环境 两个类:书的类别和文章,一片文章只能有一个作者,一个作者可以有多个文章,这之间组成了一对多的关系 class Category(models.Model): category = mod ...
- 完美解决该死的ie6下select总是置于最上层bug
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- HTML元素脱离文档流的三种方法
一.什么是文档流? 将窗体自上而下分成一行一行,并在每行中按从左至右依次排放元素,称为文档流,也称为普通流. 这个应该不难理解,HTML中全部元素都是盒模型,盒模型占用一定的空间,依次排放在HTML中 ...