赞
踩
错误描述:类型转换时提示异常!
java.lang.ClassCastException: java.lang.String cannot be cast to com.example....
调试找到问题原因:下列代码有问题(一脸懵逼,不知因为啥报错)
SecurityUtils.getSubject().getPrincipal();
一开始不知云云,网上面百度了一下,了解到是项目启动时加载项目中的类使用的加载器都是
org.springframework.boot.devtools.restart.classloader.RestartClassLoader
而从shiro session 取出来的对象(从redis中取出经过反序列化)的类加载器都是
sun.misc.Launcher.AppClassLoader
网上说的热部署等等,都试了一遍,都不好使(可能改的不对,也可能针对的错误类型不一样)
后来想的,转对象不行,转其他的试试,是什么个情况,于是就改成下面的代码!
String username = (String)SecurityUtils.getSubject().getPrincipal();
虽然问题解决了,然而!...
还是一脸懵逼,为什么转对象不行,转成String类型后为什么是一个用户名??
往上搜了一下,没搜到,后期持续关注,有结果后续更新。。。
接续,进到方法中了解的一下,getSubject() 方法
- public static Subject getSubject() {
- Subject subject = ThreadContext.getSubject();
- if (subject == null) {
- subject = (new Builder()).buildSubject();
- ThreadContext.bind(subject);
- }
-
- return subject;
- }
可以看下这篇对于ThreadContext的介绍:Shiro学习笔记(一)ThreadContext源码解析
- //日志相关
- private static final Logger log = LoggerFactory.getLogger(ThreadContext.class);
- //获取SecurityManager 对应的key
- public static final String SECURITY_MANAGER_KEY = ThreadContext.class.getName() + "_SECURITY_MANAGER_KEY";
- //获取Subject对应的key
- public static final String SUBJECT_KEY = ThreadContext.class.getName() + "_SUBJECT_KEY";
- /*通过ThreadLocalMap来存储线程自己的SecurityManager对象以及Subject对象(ThreadLocal 因此这里的操作都是线程安全地)*/
- private static final ThreadLocal<Map<Object, Object>> resources = new ThreadContext.InheritableThreadLocalMap();
-
- public static Subject getSubject() {
- return (Subject)get(SUBJECT_KEY);
- }
接下来接续查看..
-
-
- public static Object get(Object key) {
- if (log.isTraceEnabled()) {
- String msg = "get() - in thread [" + Thread.currentThread().getName() + "]";
- log.trace(msg);
- }
-
- Object value = getValue(key);
- if (value != null && log.isTraceEnabled()) {
- String msg = "Retrieved value of type [" + value.getClass().getName() + "] for key [" + key + "] " + "bound to thread [" + Thread.currentThread().getName() + "]";
- log.trace(msg);
- }
-
- return value;
- }

getValue(key)
- private static final ThreadLocal<Map<Object, Object>> resources = new ThreadContext.InheritableThreadLocalMap();
-
- private static Object getValue(Object key) {
- Map<Object, Object> perThreadResources = (Map)resources.get();
- return perThreadResources != null ? perThreadResources.get(key) : null;
- }
返回的是一个主体对象(我想这里应该就会获取到主体中的用户名称)
getPrincipal();
该对象包含当前授权用户的名称
-
- public interface Subject {
- Object getPrincipal();
-
- PrincipalCollection getPrincipals();
-
- boolean isPermitted(String var1);
-
- boolean isPermitted(Permission var1);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。