当前位置:   article > 正文

SpringBoot整合shiro-用户授权时遇到的问题:java.lang.ClassCastException_java.lang.string cannot be cast to com.example.dem

java.lang.string cannot be cast to com.example.demo.entity.sysuser

错误描述:类型转换时提示异常!

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() 方法

  1. public static Subject getSubject() {
  2. Subject subject = ThreadContext.getSubject();
  3. if (subject == null) {
  4. subject = (new Builder()).buildSubject();
  5. ThreadContext.bind(subject);
  6. }
  7. return subject;
  8. }

 可以看下这篇对于ThreadContext的介绍:Shiro学习笔记(一)ThreadContext源码解析

  1. //日志相关
  2. private static final Logger log = LoggerFactory.getLogger(ThreadContext.class);
  3. //获取SecurityManager 对应的key
  4. public static final String SECURITY_MANAGER_KEY = ThreadContext.class.getName() + "_SECURITY_MANAGER_KEY";
  5. //获取Subject对应的key
  6. public static final String SUBJECT_KEY = ThreadContext.class.getName() + "_SUBJECT_KEY";
  7. /*通过ThreadLocalMap来存储线程自己的SecurityManager对象以及Subject对象(ThreadLocal 因此这里的操作都是线程安全地)*/
  8. private static final ThreadLocal<Map<Object, Object>> resources = new ThreadContext.InheritableThreadLocalMap();
  9. public static Subject getSubject() {
  10. return (Subject)get(SUBJECT_KEY);
  11. }

 接下来接续查看..

  1. public static Object get(Object key) {
  2. if (log.isTraceEnabled()) {
  3. String msg = "get() - in thread [" + Thread.currentThread().getName() + "]";
  4. log.trace(msg);
  5. }
  6. Object value = getValue(key);
  7. if (value != null && log.isTraceEnabled()) {
  8. String msg = "Retrieved value of type [" + value.getClass().getName() + "] for key [" + key + "] " + "bound to thread [" + Thread.currentThread().getName() + "]";
  9. log.trace(msg);
  10. }
  11. return value;
  12. }

getValue(key)

  1. private static final ThreadLocal<Map<Object, Object>> resources = new ThreadContext.InheritableThreadLocalMap();
  2. private static Object getValue(Object key) {
  3. Map<Object, Object> perThreadResources = (Map)resources.get();
  4. return perThreadResources != null ? perThreadResources.get(key) : null;
  5. }

返回的是一个主体对象(我想这里应该就会获取到主体中的用户名称)

getPrincipal();

该对象包含当前授权用户的名称

  1. public interface Subject {
  2. Object getPrincipal();
  3. PrincipalCollection getPrincipals();
  4. boolean isPermitted(String var1);
  5. boolean isPermitted(Permission var1);

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/214004
推荐阅读
相关标签
  

闽ICP备14008679号