转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudespringboothoutailanjieqi60/

之前咱们把用户登录,注册成功的信息都放到redis里面了,如果产品经理有一种场景,就是同一个用户在同一个时间以最后一个登录为准,那么前一个就需要重新登录,并且清空前一个用户缓存。这就用到了springboot的缓存机制。源码:https://github.com/limingios/wxProgram.git 中No.15和springboot

拦截器的创建

通过前端传递过来的userToken,和从redis里面获取到的userToken对比,如果不一致,前端传递过来的这个session奖杯提示用户被挤出,直接缓存失效。需要重新登录。

package com.idig8.controller.interceptor;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import com.idig8.utils.JSONResult;
import com.idig8.utils.JsonUtils;
import com.idig8.utils.RedisOperator; public class MiniInterceptor implements HandlerInterceptor { @Autowired
public RedisOperator redis;
public static final String USER_REDIS_SESSION = "user-redis-session"; /**
* 拦截请求,在controller调用之前
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object arg2) throws Exception {
String userId = request.getHeader("headerUserId");
String userToken = request.getHeader("headerUserToken"); if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userToken)) {
String uniqueToken = redis.get(USER_REDIS_SESSION + ":" + userId);
if (StringUtils.isEmpty(uniqueToken) && StringUtils.isBlank(uniqueToken)) {
System.out.println("请登录...");
returnErrorResponse(response, new JSONResult().errorTokenMsg("请登录..."));
return false;
} else {
if (!uniqueToken.equals(userToken)) {
System.out.println("账号被挤出...");
returnErrorResponse(response, new JSONResult().errorTokenMsg("账号被挤出..."));
return false;
}
}
} else {
System.out.println("请登录...");
returnErrorResponse(response, new JSONResult().errorTokenMsg("请登录..."));
return false;
} /**
* 返回 false:请求被拦截,返回
* 返回 true :请求OK,可以继续执行,放行
*/
return true;
} public void returnErrorResponse(HttpServletResponse response, JSONResult result)
throws IOException, UnsupportedEncodingException {
OutputStream out=null;
try{
response.setCharacterEncoding("utf-8");
response.setContentType("text/json");
out = response.getOutputStream();
out.write(JsonUtils.objectToJson(result).getBytes("utf-8"));
out.flush();
} finally{
if(out!=null){
out.close();
}
}
} /**
* 请求controller之后,渲染视图之前
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
} /**
* 请求controller之后,视图渲染之后
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
} }

每一个拦截器有需要实现HandlerInterceptor接口,这个接口有三个方法,每个方法会在请求调用的不同时期完成,因为我们需要在接口调用之前拦截请求判断是否登陆,所以这里需要使用preHandle方法,在里面是验证逻辑,最后返回true或者false,确定请求是否合法。

拦截器加入配置中

原来咱们在spring mvc的时候都是通过xml配置文件的方法,springboot为了简化,都是通过java来进行配置,刚创建的拦截器需要配置在webconfig里面

package com.idig8;

import org.springframework.beans.factory.annotation.Value;
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.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.idig8.controller.interceptor.MiniInterceptor; @Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter { @Value("${server.file.path}")
private String fileSpace; @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//资源的路径.swagger2的资源.所在的目录,
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/")
.addResourceLocations("file:"+fileSpace); } @Bean
public MiniInterceptor miniInterceptor() {
return new MiniInterceptor();
} @Override
public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(miniInterceptor()).addPathPatterns("/user/**")
.addPathPatterns("/video/upload", "/video/uploadCover")
.addPathPatterns("/bgm/**"); super.addInterceptors(registry);
} }

小程序针对返回的502问题添加判断

在通过userId获取用户的信息时,在header中添加用户的userId,userToken,针对登录后返回502进行提示并清空用户信息缓存。

“` javascript
// pages/mine/mine.js
const app = getApp()
var videoUtils = require(‘../../utils/videoUtils.js’)
Page({

/**
* 页面的初始数据
*/
data: {
faceImage: “../../resource/images/noneface.png”,
nickname: “昵称”,
fansCounts: 0,
followCounts: 0,
receiveLikeCounts: 0,
},
/**
* 用户注销
*/
logout: function(e) {
var user = app.getGlobalUserInfo();
wx.showLoading({
title: ‘正在注销中。。。’
});
wx.request({
url: app.serverUrl + “/logout?userId=” + user.id,
method: “POST”,
header: {
‘content-type’: ‘application/json’ // 默认值
},
success: function(res) {
console.log(res.data);
var status = res.data.status;
wx.hideLoading();
if (status == 200) {
wx.showToast({
title: “用户注销成功~!”,
icon: ‘none’,
duration: 3000
})
// app.userInfo = null;
wx.removeStorageSync(“userInfo”);
wx.redirectTo({
url: ‘../userRegister/userRegister’,
})

    } else if (status == 500) {
wx.showToast({
title: res.data.msg,
icon: 'none',
duration: 3000
})
}
}
})

},
/**
* 头像上传
*/
uploadFace: function(e) {
// var user = app.userInfo;
var user = app.getGlobalUserInfo();
var me = this;
wx.chooseImage({
count: 1, // 默认9
sizeType: [‘compressed’], // 可以指定是原图还是压缩图,默认二者都有
sourceType: [‘album’, ‘camera’], // 可以指定来源是相册还是相机,默认二者都有
success: function(res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
var tempFilePaths = res.tempFilePaths
if (tempFilePaths.length > 0) {
console.log(tempFilePaths[0]);
wx.uploadFile({
url: app.serverUrl + “/user/uploadFace?userId=” + user.id, //仅为示例,非真实的接口地址
filePath: tempFilePaths[0],
name: ‘file’,
success: function(res) {
var data = JSON.parse(res.data);
console.log(data);
wx.hideLoading();
if (data.status == 200) {
wx.showToast({
title: “用户上传成功~!”,
icon: ‘none’,
duration: 3000
})
me.setData({
faceUrl: app.serverUrl + data.data
})

          } else if (data.status == 500) {
wx.showToast({
title: data.msg,
icon: 'none',
duration: 3000
})
}
}
})
} }
})

},
/**
* 生命周期函数–监听页面加载
*/
onLoad: function(options) {
var me = this;
var userInfo = app.getGlobalUserInfo();
wx.showLoading({
title: ‘正在获取用户信息。。。’
});
wx.request({
url: app.serverUrl + “/user/queryByUserId?userId=” + userInfo.id,
method: “POST”,
header: {
‘content-type’: ‘application/json’, // 默认值
‘headerUserId’: userInfo.id,
‘headerUserToken’: userInfo.userToken
},
success: function(res) {
console.log(res.data);
var status = res.data.status;

    if (status == 200) {
var userInfo = res.data.data;
wx.hideLoading();
var faceImage = me.data.faceUrl;
if (userInfo.faceImage != null && userInfo.faceImage != '' && userInfo.faceImage != undefined) {
faceImage = app.serverUrl + userInfo.faceImage;
}
me.setData({
faceImage: faceImage,
fansCounts: userInfo.fansCounts,
followCounts: userInfo.followCounts,
receiveLikeCounts: userInfo.receiveLikeCounts,
nickname: userInfo.nickname
})
} else if (status == 502){
wx.showToast({
title: res.data.msg,
duration:3000,
icon:'none',
complete:function(){
wx.removeStorageSync("userInfo"); wx.navigateTo({
url: '../userLogin/userLogin',
})
}
}) }
}
})

},

uploadVideo: function(e) {
videoUtils.uploadVideo();
},

/**
* 生命周期函数–监听页面初次渲染完成
*/
onReady: function() {

},

/**
* 生命周期函数–监听页面显示
*/
onShow: function() {

},

/**
* 生命周期函数–监听页面隐藏
*/
onHide: function() {

},

/**
* 生命周期函数–监听页面卸载
*/
onUnload: function() {

},

/**
* 页面相关事件处理函数–监听用户下拉动作
*/
onPullDownRefresh: function() {

},

/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {

},

/**
* 用户点击右上角分享
*/
onShareAppMessage: function() {

}
})
““

PS:通过拦截器的方式很好的保护后台的程序正常的运行。

「小程序JAVA实战」小程序的springboot后台拦截器(61)的更多相关文章

  1. 「小程序JAVA实战」小程序的页面重定向(60)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeyemianzhongdingxiang59/ 在我们正常的浏览网 ...

  2. 「小程序JAVA实战」小程序的留言和评价功能(70)

    转自:https://idig8.com/2018/10/28/xiaochengxujavashizhanxiaochengxudeliuyanhepingjiagongneng69/ 目前小程序这 ...

  3. 「小程序JAVA实战」小程序的视频点赞功能开发(62)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeshipindianzangongnengkaifa61/ 视频点 ...

  4. 「小程序JAVA实战」小程序的flex布局(22)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-22/ 之前已经把小程序的框架说完了,接下来说说小程序的组件,在说组件之前,先说说布局吧.源码:ht ...

  5. 「小程序JAVA实战」小程序的视频展示页面初始化(63)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeshipinzhanshiyemianchushihua62/ 进 ...

  6. 「小程序JAVA实战」小程序开发注册用户的接口(33)

    转自:https://idig8.com/2018/08/30/xiaochengxujavashizhanxiaochengxukaifazhuceyonghudejiekou33/ 从用户注册接口 ...

  7. 「小程序JAVA实战」小程序的举报功能开发(68)

    转自:https://idig8.com/2018/09/25/xiaochengxujavashizhanxiaochengxudeweixinapicaidancaozuo66-2/ 通过点击举报 ...

  8. 「小程序JAVA实战」小程序的个人信息作品,收藏,关注(66)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudegerenxinxizuopinshoucangguanzhu65 ...

  9. 「小程序JAVA实战」小程序的关注功能(65)

    转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeguanzhugongneng64/ 在个人页面,根据发布者个人和 ...

随机推荐

  1. Mysql04

    mysql: dbs 数据库系统 bdms 数据库管理系统 bda 数据库管理员 db 数据库 dba通过dbms来操作db! 关系型数据库和非关系型数据库 登录mysql mysql -h主机地址 ...

  2. C#如何弹出输入框

    在C#中,进行windows窗体应用程序编程的时候,经常需要弹出输入框,输入密码,输入文本之类的.然而,C#中没有直接弹出输入框的语句,MessageBox只能显示一段消息而不能输入.我们需要调用Mi ...

  3. 如何创建管理员权限的CMD命令提示符窗口

    最近在使用netstat -anob命令时提示 请求的操作需要提升. 总结了几种创建管理员权限的CMD命令行的方法. 创建临时管理员权限的CMD Win8系统: 按下windows徽标,直接输入cmd ...

  4. 第12课:HTML+CSS的基础用法

    1. html之head部分的常用标签的使用 <!--指定html是标准的html还是其它的html--> <!DOCTYPE html> <html lang=&quo ...

  5. 【转】MongoDB 3.0 正式版本即将发布,强力推荐

    MongoDB 今天宣布3.0 正式版本即将发布.这标志着 MongoDB 数据库进入了一个全新的发展阶段,提供强大.灵活而且易于管理的数据库管理系统. MongoDB 3.0 在性能和伸缩性方面都有 ...

  6. Scrum立会报告+燃尽图(3)选题

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2193 一.小组介绍 组长:刘莹莹 组员:朱珅莹 孙韦男 祝玮琦 王玉潘 ...

  7. LRY_FX_Assist(辅助EA)

    功能说明 辅助EA就是别的EA没有功能用这个EA来弥补,比如说风控设置(预付款.浮亏.加仓层数等达到多少进行操作),移动止损(包括隐藏移动止损),启动马丁加仓等.这个EA不能自己独立开单,只能辅助其它 ...

  8. Hive教程之metastore的三种模式

    Hive中metastore(元数据存储)的三种方式: 内嵌Derby方式 Local方式 Remote方式 [一].内嵌Derby方式 这个是Hive默认的启动模式,一般用于单元测试,这种存储方式有 ...

  9. CMS初步认识

    一CMS本质 [1]基本思想是:分离内容的管理和设计,页面显示的风格和框架存储在模板里.至于页面显示的内容存储在数据库中或一个独立的文件中.当一个用户请求页面时,各部分联合生成一个标准的 HTML 页 ...

  10. LG3389 【模板】高斯消元法

    题意 题目描述 给定一个线性方程组,对其求解 输入输出格式 输入格式: 第一行,一个正整数\(n\) 第二至\(n+1\)行,每行\(n+1\)个整数,为\(a_1, a_2 \cdots a_n\) ...