首先贴下官方文档,官方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. linux下挂载nas存储异常处理
  2. Django的mode的分组查询和聚合查询和F查询和Q查询
  3. Smart Business design time = CDS view + SADL
  4. 使用 Nginx 提升网站访问速度
  5. linux之eval命令
  6. [渝粤教育] 西南科技大学 工程测量 在线考试复习资料
  7. [react] React.createClass和extends Component的区别有哪些?
  8. 简单在于的acdsee 2012
  9. spring 5.x(1)-----Spring Framework 5.x中的新功能
  10. 201671010439-词频统计软件项目报告
  11. lua代码格式化工具_lua的代码覆盖率工具
  12. 【关系抽取】从头来看关系抽取-远程监督来袭
  13. C# 泛型LIST转DataTable
  14. python 分类 投票_使用python+redis实现文章发布,投票,分组排名功能
  15. 软考试题希赛网爬取过程分享二
  16. 51单片机用PID算法温度控制器毕业设计 完整资料,Matlab作图仿真源码
  17. macos 废纸篓强制删除文件文件夹
  18. SEO内页优化,SEO内容优化,内页快速SEO优化
  19. Linux服务器程序规范化
  20. 从技术原理解析区块链为何列入新基建

热门文章

  1. CTF解密图片得到flag
  2. HashMap循环遍历方式
  3. SECS/GEM300半导体标准,12寸晶圆半导体标准
  4. RFC821 简单邮件传输协议(SMTP)
  5. jsp重新打开一个新的页面
  6. ALU——调用加法乘法模块
  7. cake fork什么意思_方学—为了世界的爱与和平
  8. java ceiling_java.util.TreeSet.ceiling()方法实例
  9. 主角的超能力有哪些?
  10. 小明的水果店(多态与继承)