一、Redis['ri:dɪs]简介
Redis的的是完全开源免费的,是一个高性能的key-value数据库(区别于MySQL的二维表格的形式存储)是当前最热门的的的NoSql数据库之一,也被人们称为数据结构服务器
和Memcache一样,Redis数据都是缓存在计算机内存中,不同的是,Memcache只能将数据缓存到内存中,无法自动定期写入硬盘,这就表示,一断电或重启,内存清空,数据丢失。所以Memcache的应用场景适用于缓存无需持久化的数据。而Redis不同的是它会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,实现数据的持久化
· Redis速度快,读取速度是110000次/s,写的速度是81000次/s
· 支持多种数据结构:string(字符串);list(列表);hash(哈希),set(集合);zset(有序集合)
二、安装Redis以及Redis可视化工具RedisDesktopManager
双击redis-server.exe(不要关闭启动窗口,保持服务开启)其中6379是Redis服务端的默认端口,127.0.0.1是本地IP,双击redis-cli.exe进行指令测试
安装RedisDesktopManager成功后,在界面点击Connect to Redis Server,输入Name以及Host(127.0.0.1)然后Test Connection
三、Springboot整合Jedis实现Redis缓存
(1) 新建Springboot项目Spring Initializr->在Dependencies中勾选Web里的Spring Web、NoSQL里面的SpringData Redis (Access Driver)->Finish
(2) 在pom.xml文件中引入Redis缓存依赖、Jedis组件依赖:
<version>2.1.8.RELEASE</version>
<dependencies>
<!-- 打开redis缓存依赖cache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 引入Jedis组件 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
(3)配置resource目录下的application.properties文件
#redis jedis配置
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
#spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-idle=200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0
#spring-session 使用
spring.session.store-type=none
(4)建立biz业务包,新建业务类Redisbiz.java
package com.biz;
Import....
@Component
public class RedisBiz {
private String keys;
private Object value;
public boolean save(String keys,Object value){
this.keys = keys;
this.value = value;
System.out.println( "Hello World!" );
try {
Jedis jedis=new Jedis("localhost",6379);//替换为实际连接地址与端口
jedis.append(keys,value.toString());
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
(5)建立action包,新建控制器类RedisAction.java
package com.action;
import....
@RestController
public class RedisAction {
@Autowired
private RedisBiz redisBiz;
public RedisBiz getRedisBiz() {
return redisBiz;
}
public void setRedisBiz(RedisBiz redisBiz) {
this.redisBiz = redisBiz;
}
@RequestMapping(value = "save_Redis.do")
public String save(){
boolean flag=redisBiz.save("uname", "lixiaoyao");
if(flag){
return "ok";
}
return "fail";
}
}
(6)在启动类添加扫描注释
@SpringBootApplication @ComponentScan(basePackages = {"com.biz","com.action"})
(7)运行启动类DemoApplication,在浏览器输入localhost: 8080/ saveRedis.do,在RedisDesktopManager里Reload验证
IDEA运行项目后,源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示:
需在IntelliJ IDEA配置Tomcat:
点击Run---Edit Configurations...->点击左侧+号,找到Tomcat Server---Local在->Tomcat Server -> Unnamed -> Server -> Application server项目下,点击 Configuration ,找到本地 Tomcat 服务器,再点击 OK按钮
四、Token[ˈtəʊkən]简介
Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
Token也称作令牌,由uid+time+sign[+固定参数]组成:
uid: 用户唯一身份标识
time: 当前时间的时间戳
sign: 签名,使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接
固定参数(可选): 将一些常用的固定参数加入到Token中是为了避免重复查数据库
五、Token设置有效期
无论是从安全的角度考虑,还是从吊销的角度考虑,Token都需要设有效期。为了解决在操作过程不能让用户感到Token失效这个问题:
有一种方案是在服务器端保存Token状态,用户每次操作都会自动刷新(推迟)Token的过期时间。所以通常为了提升效率,减少消耗,会把Token的过期时保存在缓存或者内存中
还有另一种方案,使用Refresh Token,它可以避免频繁的读写操作。这种方案中,服务端不需要刷新Token的过期时间,一旦Token过期,就反馈给前端,前端使用Refresh Token申请一个全新Token继续使用
六、Token 验证的机制(流程)
1、用户登录校验,校验成功后就返回Token给客户端
2、客户端收到数据后保存在客户端(cookie或者请求信息)
3、客户端每次访问API是携带Token到服务器端
4、服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码
七、使用Spring boot搭建基于Token验证并将Token放入Redis中进行缓存
1、新建Springboot项目Spring Initializr->在Dependencies中勾选Developer Tools里的Springboot DevTools、Web里的Spring Web->Finish
2、在pom.xml文件中添加Token依赖的组件包、添加jsp的依赖、Redis的依赖
3、新建bean包并建立实体类Users.java(uid,uname,passwd)
4、新建util包,编写工具类TokenGeneratorUtil.java
package com.util;
...
public class TokenGeneratorUtil {
public static String getTokenUserid(String token) {
//String token = request.getHeader("token");// 从http请求头中取出 token
System.out.println("token--->"+token);
String userId = JWT.decode(token).getAudience().get(0);//从token中获取登录的id
return userId;
}
public static String getTokenGenerator(Users us){
String token=null;
Date start=new Date();
//获取系统指定的当前时间,设置token超时时间为1小时
Long cdate=System.currentTimeMillis()+60*60*1000;
Date end = new Date(cdate);
//生成token字符串
token= JWT.create().withAudience(us.getUid().toString()).withIssuedAt(start).withExpiresAt(end).sign(Algorithm.HMAC256(us.getPasswd()));
System.out.println("token--->"+token);
return token;
}
}
5、新建控制器包,建立控制器类UsersAction.java
package com.action;
import ...
@RestController
public class UsersAction {
@RequestMapping(value = "check_Users.do")
public String check(HttpServletRequest request, Users us){
us=us==null?new Users(1, "lixiaoyao", "1234356"):us;
us.setUid(41);//设置id值,主要是客户端值传递账号和密码,无编号,此处模拟从数据库取出的编号
String tokenstr=request.getHeader("token");
System.out.println("us--->"+us.getUname());
try {
//调用工具类获取Token字符串,将此token字符串发送到客户端保存
String tk=TokenGeneratorUtil.getTokenGenerator(us);
System.out.println("action-->token-->"+tk);
Jedis jedis=new Jedis("localhost",6379);//替换为实际连接地址与端口
jedis.set("mytoken",tk);
return "ok";
} catch (Exception e) {
e.printStackTrace();
}
return "fail";
}
@RequestMapping(value = "findByTokenUid_Users.do")
public String findByTokenUid(){
Jedis jedis=new Jedis("localhost",6379);//替换为实际连接地址与端口
//从redis中获取token字符串
String tokenstr=jedis.get("mytoken");
System.out.println("tokenstr-->"+tokenstr);
//使用工具类获取用户的id
String uid=TokenGeneratorUtil.getTokenUerid(tokenstr);
return uid;
}
}
6、配置application.properties
7、编写jsp页面:
首先指定Web模块的jsp路径:
先建立文件夹src->main->webapp->WEB-INF
Project Structure->Modules->Add Web->编辑路径(src->main->webapp),注意是在webapp目录下创建jsp文件:
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
</html>
<head>
<title>用户登录</title>
</head>
<body>
<form action="check_Users.do" method="post">
账号:<input type="text" name="uname" id="uname"><br>
密码:<input type="password" name="passwd" id="passwd"><br>
<input type="submit" value="确定"/>
</form>
</body>
</html>
8、启动Redis,双击redis-server.exe并打开Redis可视化工具,在启动类DemoTokenApplication添加扫描注释并启动运行,
@ComponentScan(basePackages = {"com.action"})
在浏览器输入localhost:8080 /login.jsp验证
八、能够对系统接入第三方手机短信服务
服务商:阿里云短信、腾讯云短信、百度云SMS、容联云通讯
接入步骤:
1、注册开发者账号:登陆http://www.yuntongxun.com/user/reg/init选择短信服务
开发者主账号
ACCOUNT SID:8aaf070870e20ea10170f5baeb0d0c21
AUTH TOKEN:22f47913912c455dac52974b2f9a5daa
Rest URL(生产):app.cloopen.com:8883
AppID(默认):8aaf070870e20ea10170f5baebe80c28
鉴权IP:已开启 IP设置
2、免费开发模板ID为1,形式为:“【云通讯】您使用的是云通讯短信模块,您的验证码是{1},请于{2}分钟内正确输入。”其中{1}和{2}为短信模板的参数
3、对接测试
SDK、DEMO下载:www.yuntongxun.com/doc/rest/sm…
发送模板短信接口
接口声明文件:sdk\src\com\cloopen\rest\sdk\CCPRestSDK.java
接口函数定义:public HashMap sendTemplateSMS (String to, String templateId, String[] datas)
参数说明:
to:字符串类型,短信接收手机号码集合,用英文逗号分开,如“13810001000”,最多一次发送200个
templateId:字符串类型,模板Id,如使用测试模板,模板id为"1",如使用自己创建的模板,则使用自己创建的短信模板id即可
datas:字符串数组类型,内容数据,需定义成数组方式,如模板中有两个参数,定义方式为 {"短信内容",时长}
4、在Springboot里实现对接测试
(1)新建Springboot项目Spring Initializr->在Dependencies中勾选Developer Tools里的Springboot DevTools、Web里的Spring Web->Finish
(2)在Springboot导入容联云通讯的jar包:
点击Project Structure->Modules->Dependencies->点击‘+’号->JARs or Directories...->添加容联云通讯jar包路径(jar包位于Lib中)->Apply->OK,在External libraries里查看
(3)新建test包,编写测试类SmsSendDemo.java
package com.zhaolong.test;
import...
public class SmsSendDemo {
public static void main(String[] args) {
//创建发送短信的对象
CCPRestSmsSDK ccpRestSmsSDK=new CCPRestSmsSDK();
//初始化短信服务器的地址和端口
ccpRestSmsSDK.init("app.cloopen.com","8883");
//设置账号和auth码值
ccpRestSmsSDK.setAccount("8aaf07086d05d00c016d3e65fe5820ea","04f31c810a794abdb2968734f5ca5fdd");
//设置appid
ccpRestSmsSDK.setAppId("8aaf07086d05d00c016d3e65feb420f1");
**************************************
HashMap<String,Object> result = ccpRestSmsSDK.sendTemplateSMS ("13571965070","1" ,new String[]{"测试短信!","10"});
//判断短信是否发送成功
if("000000".equals(result.get("statusCode"))){
//获取返回的消息
HashMap<String,Object> data=(HashMap<String,Object>)result.get("data");
System.out.println("短信发送成功!");
Set<String> keySet = data.keySet();
for(String key:keySet){
Object object = data.get(key);
System.out.println(key +" = "+object);
}
}else{
//异常返回输出错误码和错误信息
System.out.println("错误码=" + result.get("statusCode") +" 错误信息= "+result.get("statusMsg"));
}
}
}
(4)Run SmsSendDemo.java,在手机短信里验证
5、获取当前时间毫秒的后四位作为验证码发送到手机
(1)编写工具类SmsUtil.java
import...
public class SmsUtil {
public static CCPRestSmsSDK getccpRestSmsSDK(){
//创建发送短信的对象
CCPRestSmsSDK ccpRestSmsSDK=new CCPRestSmsSDK();
//初始化短信服务器的地址和端口
ccpRestSmsSDK.init("app.cloopen.com","8883");
//设置账号和auth码值
ccpRestSmsSDK.setAccount("8aaf07086d05d00c016d3e65fe5820ea","04f31c810a794abdb2968734f5ca5fdd");
//设置appid
ccpRestSmsSDK.setAppId("8aaf07086d05d00c016d3e65feb420f1");
return ccpRestSmsSDK;
}
}
(2)编写测试类MainTest.java
import...
public class MainTest {
public static void main(String[] args) {
//获取当前时间毫秒的后四位作为验证码
Date date=new Date();
long datetime=date.getTime();
//保留后四位数字为验证码
String val=""+datetime;
String smsck=val.substring(val.length()-4,val.length());
System.out.println("验证码-->"+smsck);
CCPRestSmsSDK ccpRestSmsSDK= SmsUtil.getccpRestSmsSDK();
ccpRestSmsSDK.sendTemplateSMS("13571965070", "1", new String[]{smsck,"10"});
}
}
九、IDEA中使用MyBatis Generator逆向工程生成代码
新建Maven项目(Springboot项目也行)->不用勾选Dependencies->Finish
(1)配置Maven pom.xml 文件
在<plugin>标签添加:
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
</plugin>
(2)在项目下的src/main/resources 目录下建立Maven的项目配置文件:generatorConfig.xml和generator.properties
generatorConfig.xml文档内容省略,在generatorConfig.xml文档中配置包名以及添加数据库表,当出现报错提示,可点击Fetch External resource来修复
generator.propertites代码如下:
jdbc.driverLocation=d:\\mysql-connector-java-5.1.9-bin.jar #数据库jar包
jdbc.driverClass=com.mysql.jdbc.Driver #数据库驱动
jdbc.connectionURL=jdbc:mysql:///itripdb #数据库名称
jdbc.userId=root
jdbc.password=java
(3)新建po、mapper包,Run->Edit Configuration->点击’+’号选择Maven,在Command line中添加如下代码: mybatis-generator:generate -e
(4)运行项目,在新建的po、mapper包内验证查看