使用 Jackson 序列化和反序列化 java.sql.Blob 的方法

Jackson
Remote
1
06:51 PM · Nov 30 ,2025

1. 簡介

在本文中,我們將學習如何使用 Jackson 序列化和反序列化 java.sql.Blobjava.sql.Blob 代表 Java 中的 Binary Large Object (Blob),可以存儲大量的二進制數據。 在使用 Jackson 進行 JSON 序列化和反序列化時,處理 Blob 對象可能比較棘手,因為 Jackson 不直接支持它們。 但是,我們可以創建自定義序列化器和反序列器來處理 Blob 對象。

我們將從設置環境和簡單的示例開始。 稍後,我們將快速演示如何實現自定義序列化器和反序列器以處理 Blob 數據類型。 最後,我們將使用我們的簡單用例測試方法驗證我們的方法。

2. 依賴與示例設置

首先,請確保我們已在項目中添加了必要的 jackson-databind 依賴項:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>

接下來,我們將演示如何在典型的POJO中集成 Blob 字段,並強調自定義序列化和反序列化的需求。讓我們創建一個簡單的 User POJO,其中包含 IDnameprofilePictureprofilePicture 的類型為 Blob

public class User {
    private int id;
    private String name;
    private Blob profilePicture;
    //構造函數
    //Getter 和 Setter
}

稍後,我們將使用此 User 類來演示涉及 Blob 字段的自定義序列化和反序列化。

3. 定義 Blob 序列化器

讓我們定義一個序列化器,將 profilePicture 屬性從 User 對象轉換為 Base64 編碼的二進制字符串:

@JacksonStdImpl
public class SqlBlobSerializer extends JsonSerializer<Blob> {
    @Override
    public void serialize(Blob value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        try {
            byte[] blobBytes = value.getBytes(1, (int) value.length());
            gen.writeBinary(blobBytes);
        } catch (Exception e) {
            throw new IOException("Failed to serialize Blob", e);
        }
    }
}

重要的是,@JacksonStdImpl 是一個標記註解,通常用於 Jackson 的內置序列化器和反序列器。

我們的 SqlBlobSerializer 繼承了 JsonSerializer<Blob>,這是一個 Jackson 提供的泛型類,用於定義自定義序列化器。我們覆蓋了 `serialize` 方法,傳遞要序列化的 Blob 對象以及 JsonGenerator 和 SerializerProviderJsonGenerator 用於生成生成的 JSON 內容,而 SerializerProvider 用於提供用於序列化對象的序列化器。

本質上,serialize 方法使用 getBytes()Blob 轉換為字節數組。然後,它使用 gen.writeBinary() 將字節數組作為 Base64 編碼的二進制字符串寫入。

5.  定義 Blob 解序列化器

現在我們定義一個解序列化器,它可以使用 Jackson 將 Base64 編碼的字符串轉換為 Blob:

@JacksonStdImpl
public class SqlBlobDeserializer extends JsonDeserializer<Blob> {
    @Override
    public Blob deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        try {
            byte[] blobBytes = p.getBinaryValue();
            return new SerialBlob(blobBytes);
        } catch (Exception e) {
            throw new IOException("Failed to deserialize Blob", e);
        }
    }
}

這裏,SqlBlobDeserializer 繼承了 JsonDeserializer<Blob>, 這是一個 Jackson 提供的用於定義自定義解序列化器的泛型類。我們然後覆蓋了 JsonDeserializer 中的 deserialize 方法,傳入了 JsonParser,該解析器用於讀取 JSON 內容。此外,我們還傳入了 DeserializationContext,該對象可用於訪問解序列化過程的信息。

本質上,SqlBlobDeserializer 從 JSON 中檢索二進制數據到 byte[] 使用 getBinaryValue()然後,它將字節數組轉換為 SerialBlob 對象,該對象是 java.sql.Blob 的實現。

6. 註冊自定義序列化器和反序列器

現在我們已經有了 BlobSerializerBlobDeserializer,下一步是使用 Jackson 註冊它們。 使用 Jackson 註冊自定義序列化器和反序列器意味着配置 Jackson 的 ObjectMapper 以使用特定類來將某些 Java 對象轉換為 JSON 和反向轉換。 讓我們創建一個 SimpleModule,並將我們的 blobSerializerblobDeserializer 添加到該模塊中:

SimpleModule module = new SimpleModule();
module.addSerializer(Blob.class, new SqlBlobSerializer());
module.addDeserializer(Blob.class, new SqlBlobDeserializer());

接下來,讓我們創建一個 ObjectMapper,並將該模塊註冊到它上:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);

本質上,通過將特定模塊註冊到 ObjectMapper 上,我們確保它知道如何處理 JSON 處理期間的非標準類型。 在這種情況下,我們確保我們的 <em>ObjectMapper</em> 知道如何使用我們的自定義序列化器和 deserializer 處理 <em>Blob</em> 類型。

7. 單元測試

最後,讓我們通過編寫單元測試來查看我們的註冊序列化器和反序列器在行動中的效果。 讓我們首先測試 BlobSerializer ,然後是 BlobSerializer

@Test
public void givenUserWithBlob_whenSerialize_thenCorrectJsonDataProduced() throws Exception {
    User user = new User();
    user.setId(1);
    user.setName("Test User");
    //sample blob data from byte[]
    byte[] profilePictureData = "example data".getBytes();
    Blob profilePictureBlob = new SerialBlob(profilePictureData);
    user.setProfilePicture(profilePictureBlob);

    String json = mapper.writeValueAsString(user);
    String expectedJson = "{\"id\":1,\"name\":\"Test User\",\"profilePicture\":\"ZXhhbXBsZSBkYXRh\"}";
    assertEquals(expectedJson, json);
}

該測試驗證序列化後的 JSON 字符串與預期 JSON 格式匹配。 具體來説,JSON 中的 profilePicture 字段預計是一個 base64 編碼的字符串,表示 Blob 數據。

接下來,讓我們為 BlobDeserializer 編寫一個測試。

@Test
public void givenUserJsonWithBlob_whenDeserialize_thenCorrectDataRecieved() throws Exception {
    String json = "{\"id\":1,\"name\":\"Test User\",\"profilePicture\":\"ZXhhbXBsZSBkYXRh\"}";
    User deserializedUser = mapper.readValue(json, User.class);
    assertEquals(1, deserializedUser.getId());
    assertEquals("John Doe", deserializedUser.getName());

    byte[] expectedProfilePictureData = "example data".getBytes();
    Blob deserializedProfilePictureBlob = deserializedUser.getProfilePicture();
    byte[] deserializedData = deserializedProfilePictureBlob.getBytes(1, (int) deserializedProfilePictureBlob.length());
    assertArrayEquals(expectedProfilePictureData, deserializedData);
}

在此處,Blob 數據預計與原始字節數據“example data”匹配。 此測試確保自定義 SqlBlobDeserialiser 正確地將 base64 編碼的字符串轉換回一個 Blob 對象,並在 User 對象內部保留原始二進制數據。

8. 結論

在本文中,我們演示瞭如何有效地使用 Jackson 庫在 Java 中序列化和反序列化 java.sql.Blob 對象的方法。我們創建了自定義的序列化器和反序列器來處理 Blob 對象中的二進制數據,將其轉換為和從 JSON 格式中的 base64 編碼字符串。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.