项目持续创作中:
目录
安装redis6.0缓存中间件
整合Redis并存储验证码
拦截器限制60s短信发送
优雅异常封装返回拦截器异常
安装redis6.0缓存中间件
需要安装到我们的linux中,这里我们可以通过FTP工具将我们的文件上传linux
连接进来之后:(redis是基于c开发的)
先安装环境
继续:
安装成功之后:
升级命令:
这里gcc已经升级完成:
我们要永久安装gcc环境:
接着要开始正式安装redis:(解压缩)
进入redis:
make安装:
先编译再安装到指定目录
相关的文件有了:
回到目录,拷贝redis.conf核心配置文件
此时配置完成
配置文件中我们要做相应的修改:
看我们的redis是以前台的形式启动还是后台,我们做一个开启
绑定我们的id为0.0.0.0,任何只要能在这个节点,服务能够互通的,都能够连接到redis服务
保存再进入,设置密码
设置log日志,日志输出就会放在目录中
启动我们的redis,携带核心配置文件
此时已经运行了。
redis库,默认16个db
回到控制台:
整合Redis并存储验证码
在common中引入redis依赖:
Maven中刷新
RedisOperation在common中作为我们的工具类
Spingboot作为我们的客户端,连接我们的server。
配置redis:
整合成功。在构建一个BaseController,在里面放入公用的方法
需要修改的:
package com.imooc.controller;
import com.imooc.grace.result.GraceJSONResult;
import com.imooc.model.Stu;
import com.imooc.utils.IPUtil;
import com.imooc.utils.SMSUtils;
import com.tencentcloudapi.ie.v20200304.models.MuxInfo;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@Api(tags = "PassportController 通行证接口模块")
@RequestMapping("passport")
@RestController
public class PassportController extends BaseController{
@Autowired
private SMSUtils smsUtils;
@PostMapping("getSMSCode")
public Object getSMSCode(@RequestParam String mobile,
HttpServletRequest request) throws Exception {
// 判断是否为空,为空什么信息都不返回
if(StringUtils.isBlank(mobile)){
return GraceJSONResult.ok();
}
//
//TODO 获取用户id
String userIp = IPUtil.getRequestIp(request);
//TODO 根据用户ip进行限制,限制用户在60s之内只能获得一次验证码
redis.setnx60s(MOBILE_SMSCODE+":"+userIp,userIp);
// 获取6位随机验证码
String code = (int)((Math.random()*9+1)*100000)+"";
smsUtils.sendSMS("15397609967",code);
log.info(code);
//TODO 把验证码放入redis中,用于后续验证
redis.set(MOBILE_SMSCODE+":"+mobile,code,30*60);
return GraceJSONResult.ok();
}
}
运行,打开手机基座,发送验证码:
打开redis可视化工具,有两栏
第一个key是我们的ip地址
TTL就是剩余的时间
外层刷新:
下一个key是我们的手机号,与前端一致:
拦截器限制60s短信发送
在springboot增加一个拦截器,创建一个包,建一个PassportInterceptor类
cmd+i生成:
在PassportInterceptor中:
package com.imooc.interceptor;
import com.imooc.controller.BaseInfoProperties;
import com.imooc.utils.IPUtil;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PassportInterceptor extends BaseInfoProperties implements HandlerInterceptor {
// 访问controller之前,请求会被拦截
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//获得用户ip
String useIp = IPUtil.getRequestIp(request);
return false;
}
//请求访问到controller之后,渲染视图之前,会到达
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
//整个请求结束,走完controller,渲染试图之后,
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
保留BaseController,复制一份,修改:
重新修改:
接下里重新启动:
在接口文档中进行调试:
此时手机会收到短信,但是我们这时候是没有做到限制的,所以我们要在Intercept增加一个拦截器:
创建一个类:
package com.imooc;
import com.imooc.interceptor.PassportInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptConfig implements WebMvcConfigurer {
@Bean
public PassportInterceptor passportInterceptor(){
return new PassportInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(passportInterceptor())
.addPathPatterns("/passport/getSMSCode");
}
}
重启,打开文档发送:
得不到相应内容,因为被拦截了:
优雅异常封装返回拦截器异常
上面虽然我们完成了打印,但是并没有反馈给我们的前端:
我们可以通过自定义异常捕获,把异常信息解耦发给前端,在这里我们添加几个异常捕获工具类
在这里添加优雅响应,
display里
这个类可以不要,把throw这段话放在interceptor也是可以的,但是不太优雅,我们不要让它暴露在其他类中。
统一对异常拦截和处理 :
底层原理是切面,
通过e.get获取枚举信息,相应的错误信息就能以json形式抛给前端。
重启,文档中连续发送两次:
到这里就完成了我们的优雅异常封装返回拦截器异常。