首先贴下官方文档,官方sa-token文档;看了一圈都是集成SpringBoot,我用bean注入看起来是先例哦哈哈,好咯,不跟你多bb,直接上代码

代码我放在了GITEE中了需要自取,传送门

  1. 改applicationContext.xml(只有增加的哦)
  <!-- 加载配置文件 --><context:property-placeholder location="classpath:redis.properties"/><!-- Sa-Token--><bean class="org.springframework.boot.autoconfigure.EnableAutoConfiguration" abstract="true"></bean><bean class="cn.dev33.satoken.spring.SaBeanRegister"/><bean class="cn.dev33.satoken.spring.SaBeanInject"><property name="config" ref="sa-token"/></bean><!--自己看SaAloneRedisInject重写的路径--><bean class="top.jacktgq.controller.SaAloneRedisInject"></bean><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxIdle" value="300"/> <!--最大能够保持idel状态的对象数--><property name="maxTotal" value="60000"/><!--最大分配的对象数--><property name="testOnBorrow" value="true"/><!--当调用borrow Oject方法时,是否进行有效性检查--></bean><bean primary="true" id="redisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"p:hostName="${redis.host}"p:port="${redis.port}"p:database="${redis.database}"/><bean name="saTokenDao" class="cn.dev33.satoken.dao.SaTokenDaoRedisJackson"></bean><!--sa-token配置--><bean id="sa-token" class="cn.dev33.satoken.config.SaTokenConfig"><!--token名称 (同时也是cookie名称)--><property name="tokenName" value="satoken"></property><!--token有效期,单位s 默认30天, -1代表永不过期--><property name="timeout" value="2592000"></property><!--token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒--><property name="activityTimeout" value="-1"></property><!--是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)--><property name="isConcurrent" value="false"></property><!--在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)--><property name="isShare" value="true"></property><!--token风格--><property name="tokenStyle" value="uuid"></property><!--是否输出操作日志--><property name="isLog" value="true"/><property name="sso" ref="sso"/></bean><!--# SSO-相关配置--><bean id="sso" class="cn.dev33.satoken.config.SaSsoConfig"><!--  # SSO-Server端 统一认证地址--><property name="authUrl" value="http://xka.com:8883/sso/auth"/><!--# 是否打开单点注销接口--><property name="isSlo" value="true"/></bean>
  1. 增加redis.properties
redis.host=127.0.0.1
redis.port=6379
redis.password=
redis.database=1
redis.maxActive=300
redis.maxWait=1000
redis.testOnBorrow=true
redis.timeout=100000sa-token.alone-redis=6666
sa-token.alone-redis.host=6976fep.local.cache.capacity =10000
  1. 重写SaAloneRedisInject类的方法,至于为什么重写,是因为,他有一个地方要获取SpringBoot的配置的 host,但是我们是SpringMVC的故而就直接重写它
package top.jacktgq.controller;import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;import cn.dev33.satoken.dao.SaTokenDaoRedisJackson;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Lettuce;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import top.jacktgq.utils.PropertiesLoader;/*** 为 SaTokenDao 单独设置Redis连接信息 * @author kong*/
@Configuration
public class SaAloneRedisInject implements EnvironmentAware {/*** 配置信息的前缀 */public static final String ALONE_PREFIX = "sa-token.alone-redis";/*** Sa-Token 持久层接口 */@Autowired(required = false)public SaTokenDao saTokenDao;/*** 开始注入 */@Overridepublic void setEnvironment(Environment environment) {try {// 如果为空或者默认实现,则不进行任何操作 if(saTokenDao == null || saTokenDao instanceof SaTokenDaoDefaultImpl) {return;}// 如果配置文件不包含相关配置,则不进行任何操作 /*if(environment.getProperty(ALONE_PREFIX + ".host") == null) {return;}*/// ------------------- 开始注入 // 获取cfg对象 //RedisProperties cfg = Binder.get(environment).bind(ALONE_PREFIX, RedisProperties.class).get();RedisProperties cfg = getSaAloneRedisConfig();// 1. Redis配置 RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();redisConfig.setHostName(cfg.getHost());redisConfig.setPort(cfg.getPort());redisConfig.setDatabase(cfg.getDatabase());redisConfig.setPassword(RedisPassword.of(cfg.getPassword())); // 2. 连接池配置 GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();// pool配置 Lettuce lettuce = cfg.getLettuce();if(lettuce.getPool() != null) {RedisProperties.Pool pool = cfg.getLettuce().getPool();// 连接池最大连接数poolConfig.setMaxTotal(pool.getMaxActive()); // 连接池中的最大空闲连接 poolConfig.setMaxIdle(pool.getMaxIdle());    // 连接池中的最小空闲连接poolConfig.setMinIdle(pool.getMinIdle());     // 连接池最大阻塞等待时间(使用负值表示没有限制)poolConfig.setMaxWaitMillis(pool.getMaxWait().toMillis());}LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();// timeout if(cfg.getTimeout() != null) {builder.commandTimeout(cfg.getTimeout());}// shutdownTimeout if(lettuce.getShutdownTimeout() != null) {builder.shutdownTimeout(lettuce.getShutdownTimeout());}// 创建Factory对象 LettuceClientConfiguration clientConfig = builder.poolConfig(poolConfig).build();LettuceConnectionFactory factory = new LettuceConnectionFactory(redisConfig, clientConfig);factory.afterPropertiesSet();// 3. 开始初始化 SaTokenDao // 如果是SaTokenDaoRedistry {Class.forName("cn.dev33.satoken.dao.SaTokenDaoRedis");SaTokenDaoRedis dao = (SaTokenDaoRedis)saTokenDao;dao.isInit = false;dao.init(factory);return;} catch (ClassNotFoundException e) {}// 如果是SaTokenDaoRedisJacksontry {Class.forName("cn.dev33.satoken.dao.SaTokenDaoRedisJackson");SaTokenDaoRedisJackson dao = (SaTokenDaoRedisJackson)saTokenDao;dao.isInit = false;dao.init(factory);return;} catch (ClassNotFoundException e) {}} catch (Exception e) {e.printStackTrace();}}/*** 骗过编辑器,增加配置文件代码提示* 自定义编写* @return 配置对象*/@ConfigurationProperties(prefix = ALONE_PREFIX)public RedisProperties getSaAloneRedisConfig() {RedisProperties redisProperties =new RedisProperties();PropertiesLoader propertiesLoader = new PropertiesLoader("redis.properties");redisProperties.setHost(propertiesLoader.getProperty("redis.host"));redisProperties.setPort(Integer.parseInt(propertiesLoader.getProperty("redis.port")));redisProperties.setDatabase(Integer.parseInt(propertiesLoader.getProperty("redis.database")));redisProperties.setPassword(propertiesLoader.getProperty("redis.password"));return redisProperties;}}
  1. Sa-Token持久层接口 SaTokenDaoRedis
package top.jacktgq.controller;import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.util.SaFoxUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;/*** Sa-Token持久层接口 [Redis版 (使用JDK默认序列化方式)] * * @author kong**/
@Component
public class SaTokenDaoRedis implements SaTokenDao {/*** String专用 */public StringRedisTemplate stringRedisTemplate; /*** Objecy专用 */public RedisTemplate<String, Object> objectRedisTemplate;/*** 标记:是否已初始化成功*/public boolean isInit;@Autowiredpublic void init(RedisConnectionFactory connectionFactory) {// 指定相应的序列化方案 StringRedisSerializer keySerializer = new StringRedisSerializer();JdkSerializationRedisSerializer valueSerializer = new JdkSerializationRedisSerializer();// 构建StringRedisTemplateStringRedisTemplate stringTemplate = new StringRedisTemplate();stringTemplate.setConnectionFactory(connectionFactory);stringTemplate.afterPropertiesSet();// 构建RedisTemplateRedisTemplate<String, Object> template = new RedisTemplate<String, Object>();template.setConnectionFactory(connectionFactory);template.setKeySerializer(keySerializer);template.setHashKeySerializer(keySerializer);template.setValueSerializer(valueSerializer);template.setHashValueSerializer(valueSerializer);template.afterPropertiesSet();// 开始初始化相关组件 if(this.isInit == false) {this.stringRedisTemplate = stringTemplate;this.objectRedisTemplate = template;this.isInit = true;}}/*** 获取Value,如无返空 */@Overridepublic String get(String key) {return stringRedisTemplate.opsForValue().get(key);}/*** 写入Value,并设定存活时间 (单位: 秒)*/@Overridepublic void set(String key, String value, long timeout) {if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE)  {return;}// 判断是否为永不过期 if(timeout == SaTokenDao.NEVER_EXPIRE) {stringRedisTemplate.opsForValue().set(key, value);} else {stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);}}/*** 修改指定key-value键值对 (过期时间不变) */@Overridepublic void update(String key, String value) {long expire = getTimeout(key);// -2 = 无此键 if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {return;}this.set(key, value, expire);}/*** 删除Value */@Overridepublic void delete(String key) {stringRedisTemplate.delete(key);}/*** 获取Value的剩余存活时间 (单位: 秒) */@Overridepublic long getTimeout(String key) {return stringRedisTemplate.getExpire(key);}/*** 修改Value的剩余存活时间 (单位: 秒) */@Overridepublic void updateTimeout(String key, long timeout) {// 判断是否想要设置为永久if(timeout == SaTokenDao.NEVER_EXPIRE) {long expire = getTimeout(key);if(expire == SaTokenDao.NEVER_EXPIRE) {// 如果其已经被设置为永久,则不作任何处理 } else {// 如果尚未被设置为永久,那么再次set一次this.set(key, this.get(key), timeout);}return;}stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);}/*** 获取Object,如无返空 */@Overridepublic Object getObject(String key) {return objectRedisTemplate.opsForValue().get(key);}/*** 写入Object,并设定存活时间 (单位: 秒) */@Overridepublic void setObject(String key, Object object, long timeout) {if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE)  {return;}// 判断是否为永不过期 if(timeout == SaTokenDao.NEVER_EXPIRE) {objectRedisTemplate.opsForValue().set(key, object);} else {objectRedisTemplate.opsForValue().set(key, object, timeout, TimeUnit.SECONDS);}}/*** 更新Object (过期时间不变) */@Overridepublic void updateObject(String key, Object object) {long expire = getObjectTimeout(key);// -2 = 无此键 if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {return;}this.setObject(key, object, expire);}/*** 删除Object */@Overridepublic void deleteObject(String key) {objectRedisTemplate.delete(key);}/*** 获取Object的剩余存活时间 (单位: 秒)*/@Overridepublic long getObjectTimeout(String key) {return objectRedisTemplate.getExpire(key);}/*** 修改Object的剩余存活时间 (单位: 秒)*/@Overridepublic void updateObjectTimeout(String key, long timeout) {// 判断是否想要设置为永久if(timeout == SaTokenDao.NEVER_EXPIRE) {long expire = getObjectTimeout(key);if(expire == SaTokenDao.NEVER_EXPIRE) {// 如果其已经被设置为永久,则不作任何处理 } else {// 如果尚未被设置为永久,那么再次set一次this.setObject(key, this.getObject(key), timeout);}return;}objectRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);}/*** 搜索数据 */@Overridepublic List<String> searchData(String prefix, String keyword, int start, int size) {Set<String> keys = stringRedisTemplate.keys(prefix + "*" + keyword + "*");List<String> list = new ArrayList<String>(keys);return SaFoxUtil.searchList(list, start, size);}}
  1. 最后一点就是配置拦截器的了,@EnableWebMvc这个注解一定要加,不然没有用,我因为这个问题困扰2天
package top.jacktgq.controller;import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.spring.SpringMVCUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaFoxUtil;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import top.jacktgq.security.util.StpMemberUtil;import java.util.Arrays;@Configuration
@EnableWebMvc//开启SpringMVC支持,如无此注解,重写WebMvcConfigurerAdapter类的方法无效
@ComponentScan("top.jacktgq.controller")
public class JthinkTokenConfig implements WebMvcConfigurer {// 注册sa-token的拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 启用注解可以和下面路由拦截器(SaRouteInterceptor)同时使用registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");// 注册路由拦截器,自定义验证规则registry.addInterceptor(new SaRouteInterceptor((request, response, handler) -> {// 登录验证 -- 排除多个路径SaRouter.match(Arrays.asList("/admin/index/**"),Arrays.asList("/static/**", "/system/adminlogin", "/system/dologin", "/adminlogout"),() -> StpUtil.checkLogin());/*    // 角色认证 -- 拦截以 admin 开头的路由,必须具备[admin]角色或者[super-admin]角色才可以通过认证SaRouter.match("/admin/**", () -> StpUtil.checkRoleOr("admin", "super-admin"));// 权限认证 -- 不同模块, 校验不同权限SaRouter.match("/user/**", () -> StpUtil.checkPermission("user"));SaRouter.match("/admin/**", () -> StpUtil.checkPermission("admin"));SaRouter.match("/goods/**", () -> StpUtil.checkPermission("goods"));SaRouter.match("/orders/**", () -> StpUtil.checkPermission("orders"));SaRouter.match("/notice/**", () -> StpUtil.checkPermission("notice"));SaRouter.match("/comment/**", () -> StpUtil.checkPermission("comment"));// 匹配 restful 风格路由SaRouter.match("/article/get/{id}", () -> StpUtil.checkPermission("article"));*/// 在多账号模式下,可以使用任意StpUtil进行校验SaRouter.match(Arrays.asList("/member/**"),Arrays.asList("/member/login", "/member/dologin", "/member/register", "/member/logout"),() -> StpMemberUtil.checkLogin());})).addPathPatterns("/**");}/** 注册 [Sa-Token全局过滤器] */@Beanpublic SaServletFilter getSaServletFilter() {return new SaServletFilter().addInclude("/**").addExclude("/sso/*", "/favicon.ico").setAuth(obj -> {if(StpUtil.isLogin() == false) {String back = SaFoxUtil.joinParam(SaHolder.getRequest().getUrl(), SpringMVCUtil.getRequest().getQueryString());SaHolder.getResponse().redirect("/sso/login?back=" + SaFoxUtil.encodeUrl(back));SaRouter.back();}});}}

最后,上面基本上都配置好了,总结就是多看源码,多看文档,如果有老鸟发现博客有问题的话,大家评论一下,愚人节快乐

SpringMVC配置sa-Token相关推荐

  1. springmvc开发微信公众号接口 微信公众号测试账号配置接口Token验证

    转:springmvc开发微信公众号接口 微信公众号测试账号配置接口Token验证 开发前必读以及准备工作: 1.微信公众平台开发是指为微信公众号进行业务开发,为移动应用.PC端网站.公众号第三方平台 ...

  2. springmvc配置DispatcherServlet拦截url注意事项

    <!-- 前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-cla ...

  3. 第9步 spring 配置 springmvc配置

    spring配置 有5个网址   springboot 再讲一遍  spring的学习最好的方法是运行  官方demo  学习它里面的配置   . 我们不可能一下子理解spring里面的源码 spri ...

  4. SpringMVC配置静态资源加载, 中文乱码处理,注解驱动

    常规配置(Controller加载控制) SpringMVC的处理器对应的bean必须按照规范格式开发,未避免加入无效的bean可通过bean加载过滤器进行包含设定或排除设定,表现层bean标注通常设 ...

  5. spring boot实现WebMvcConfigurer接口定制SpringMvc配置

    文章目录 自定义静态资源映射 addResourceHandlers() 拦截器 addInterceptors() 无业务逻辑页面跳转 addViewControllers() 合而为一 sprin ...

  6. Spring Boot整合Swagger3配置全局Token

    应用背景:Swagger配置全局Token的目的在于调用真正接口前会被相关拦截器拦截,拦截器会校验此次访问是否合法,这时配置全局Token的作用就显现出来了,全局Token可以存储所有接口访问时的令牌 ...

  7. SpringMVC配置任何类型转换器 Converter(以时间类型为例)

    SpringMVC配置任何类型转换器 Converter (以时间类型为例) 从页面传到后台的时间字符串转成日期格式封装到实体类 1. 定义时间DateConverter转换类实现  Converte ...

  8. SpringMVC配置自定义过滤器

    SpringMVC配置自定义过滤器 环境 开发工具: idea2019.3.5 springmvc版本: 5.1.9.RELEASE <dependency><groupId> ...

  9. PostMan配置动态token

    PostMan配置动态token 1.在PostMan获取token接口中的Tests中添加如下代码: var jsonData = JSON.parse(responseBody); pm.envi ...

  10. 公众号基本配置(token验证失败)|公众平台测试账号接口配置信息(token验证失败)

    1.公众号基本配置(token验证失败) <?php define("TOKEN", "你自己的token");$wechatObj = new Call ...

最新文章

  1. Spark的RDD持久化
  2. 美团技术四面经历,作者已拿到Offer!
  3. 23个 Git 最常用命令速查手册,值得收藏!
  4. c语言实现文件数据删除视频,如何用c语言实现删除文件中指定的数据;例如
  5. mysql 触发器计算总价,mysql’插入’触发器根据其他字段计算字段
  6. PHP5.3以上版本没有libmysql.dll,以及由此带来的困扰
  7. 关于DG32f103C8T6 不启动的问题-调试可以运行自启动不行
  8. AtCoder Regular Contest 088 E - Papple Sort(树状数组+结论)
  9. 在Java环境下怎么打开_Java环境配置及在Dos命令下运行Java程序
  10. 【Linux设备驱动】如何挂载和卸载驱动 lsmod insmod rmmod和modprobe
  11. 在java语言中所有类都是,【填空题】(10-1)Java语言中,( )是所有 类的祖先类。
  12. 1, 定义一个基类BaseClass,从它派生出类DerivedClass。BaseClass里有成员函数fn1(),fn2(),DerivedClass也有成员函数fn1(),fn2()。在主函数中
  13. 一个jsp+cgi+html小工程,完成注册,后台使用CGI
  14. 柠檬班python自动化百度云_柠檬班python
  15. 企业微信手机端可以退出吗?会影响电脑端企业微信吗?
  16. linux 群组分类,Linux文件权限与群组修改命令详解
  17. 20200731 SCOI模拟T3(线段树分治)
  18. MariaDB 之用
  19. python软件测试书籍推荐_自学软件测试看什么书入门比较好呢?
  20. LCD屏应用--笔记

热门文章

  1. 设置windows开机自启某个软件
  2. excel求平均值AVERAGE出现#DIV/0!
  3. Asp.Net MVC WebAPI的创建与前台Jquery ajax后台HttpClient调用详解
  4. Flutter之事件处理
  5. 51单片机的智能晾衣架
  6. SQL Server 2008R2下载及安装教程
  7. grep与正则表达式匹配
  8. 什么是JavaScript
  9. 一些后端开发术语(设计/开发/通信/故障/监控/服务治理/测试/发布部署/环境/CI/CD)
  10. 南湖区青少年计算机知识竞赛,关于组织开展2012年南湖区青少年.doc