八。shiro序列化session失败,异常local class incompatible

我把session放在了数据库里,比如这样:但长时间未登录后,再次使用我记下的 JESESSIONID登录时,报错序列化失败和

local class incompatible

    protected Serializable doCreate(Session session) {  
        Serializable sessionId = super.doCreate(session); 
        //Serializable sessionId = generateSessionId(session);
        //assignSessionId(session, sessionId);

        DlUserSession userSession=new DlUserSession();
        Date now = new Date();
        userSession.setDlUserSessionId((String) sessionId);
        userSession.setDlUserSession(SerializeUtils.serialize(session));
        userSession.setDlUserSessionCreatetime(now);
        userSession.setDlUserSessionUpdatetime(now);
        userSessionMapper.insert(userSession);
        return sessionId;  
    }  
  
    //获取session  
    @Override  
    protected Session doReadSession(Serializable sessionId) {  
       Session session = super.doReadSession(sessionId);  

        if(session==null) {
        	 DlUserSession userSession = userSessionExtendMapper.getSessionBySessionId((String)sessionId);
        	 if(userSession!=null) {
              	session=(Session) SerializeUtils.deserialize(userSession.getDlUserSession());
              	//如果库有,缓存却没有,加入缓存,readsession调用次数太多
              	//super.doCreate(session);虽然可以加入缓存,但错误的 会产生新的seesionid
              	cache(session, sessionId);
        	 }
        }
        return session;  
    }  



网上查找后,明白是我更改了userInfo类,和没有加序列号的问题

参考:https://blog.csdn.net/evilcry2012/article/details/45395359点击打开链接


local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2427389723552147596

该错产生来自三个原因:

1.没有指定值:BEAN没有指定序列化值即由JDK给出,客户、服务端使用了不同版本的JDK。

=》解决:要使用相同JDK

2.没有指定值:某个类在与之对应的对象已经序列化出去后做了修改,而这个属性值由JVM根据类的相关信息计算,而修改后的类的计算结果与修改前的类的计算结果往往不同,从而造成对象的反序列化因为类版本不兼容而失败。

=》解决:要同时重启应用升级

3.指定值了:客户端BEAN和服务端的BEAN里面序列化值不同。

=》解决:最好指定,在JDK中,可以利用JDK的bin目录下的serialver.exe工具产生这个serialVersionUID,对于Test.class,执行命令:serialver Test。

 

在《谈原型模式还有JAVA克隆还有Transient》时用到对象流,能够被写进对象流的的类都必须标记一个接口序列化。
用eclipse的话,会看到一个编译警告:

The serializable class xxx does not declare a static final serialVersionUID field of type long

 八。shiro序列化session失败,异常local class incompatible_第1张图片

那么这个变量是干啥的呢?
serialVersionUID是一个用来版本控制的UID。具体可以参考这篇文章《Understand the serialVersionUID》和相关的JSL

这篇随笔为该文章的阅读笔记。

要测试serialversionUID的版本控制功能,很简单。写三个类:

一个序列化类。

一个写对象流的类。

一个读对象流的类。

当被读取的对象和当前的序列化类的UID不同时会报错。例如:

java.io.InvalidClassException:
local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2427389723552147596

 如果不给定一个UID,JVM会自动生成一个。例如上面的错误是产生于下面两段代码:

public  class SerialVersionUUIDTest  implements Serializable {
     private  static  final  long serialVersionUID = 1L;

}
复制代码
public  class SerialVersionUUIDTest  implements Serializable {

}
复制代码


默认自动生成的UID,有什么坏处呢?不同环境JVM对同一个类生成的UID可能会不同,从而产生错误。所以说采用分布式的技术或者把对象保存到数据库时应该要注意


你可能感兴趣的:(shiro)