redis反序列化出現:java.lang.ClassNotFoundException異常

不知道大家在使用redis的時候,有沒有遇到過如下錯誤:java.lang.ClassNotFoundException,這個錯誤是因爲反序列化時找不到對應的對象導致的。

什麼是序列化

在開始今天的課程之前,我們先來介紹一下:什麼是redis的系列化和反序列化。

數據想要存入redis緩存之前,需要序列化爲byte數組,從redis中取出數據,卻是一個相反的過程,需要將byte數組反序列纔可以。

刨根問題

介紹完序列化和反序列化之後,我們繼續回到剛纔的問題,爲什麼會發生ava.lang.ClassNotFoundException錯誤呢?

這個問題本質是因爲序列化和反序列化不對稱引起的,那什麼情況下會發生這種問題呢?發生這種問題又需要如何解決呢?

問題誘因

導致java.lang.ClassNotFoundException問題有:

  1. 序列化和反序列化的serialVersionUID不一致。
  2. 反序列的對象和反序列化的對象所屬的包名不一致。

處理方案

出現java.lang.ClassNotFoundException錯誤無非就是上面所說的兩種問題,第一種好解決,只要在類上面加上如下所示的代碼即可。

private static final long serialVersionUID = -5172532647273106745L;

序列化和反序列化的對象的ID需要一致(一個數字都不能錯)

第二個問題引起的反序列化問題,有兩種解決方案。序列化和反序列化的對象包命一致即可,但是有時候修改包命並不現實,可能代價會非常高,這個時候我們可以通過如下所示的代碼,在序列化之前進行包命的替換。

@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
    String name = desc.getName();
    try {
        if (name.startsWith("com.fourkmiles.monitor")) {
            // 監控項目包命替換
            name = name.replace("com.fourkmiles.monitor.model.po", "com.fourkmiles.batch.model.po.monitor");
        }
        return Class.forName(name);
    } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
    }
    return super.resolveClass(desc);
}

通過如上所示的代碼就可以不用修改包命的情況下,反序列化成功。

總結

我們在使用redis的時候,一定要去了解redis核心部分的相關原理,這樣在出現問題的時候,我們也可以快速的定位問題發生的原因,並快速解決。

後記

  1. redis中list結構類型的數據,存在多種序列化不同的相同對象,這個時候要如何進行反序列化?
  2. redis內存溢出之後,會發生什麼問題?
  3. 插入redis緩存的數據過大,要如何進行優化?

想要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裏等你哦~

林老師帶你學編程https://wolzq.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章