溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

ProtoStuff不支持BigDecimal序列化及反序列化怎么解決

發(fā)布時(shí)間:2022-08-25 10:49:22 來源:億速云 閱讀:189 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“ProtoStuff不支持BigDecimal序列化及反序列化怎么解決”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

引言

平時(shí)使用ProtoStuff作為序列化工具,對于一些POJO對象序列化,但是在實(shí)際使用中,發(fā)現(xiàn)針對BigDecimal對象進(jìn)行序列化時(shí)卻出現(xiàn)了問題

  • 不管什么數(shù),生成的byte數(shù)組都一樣

  • 無法正確反序列化

下面記錄一下這個(gè)問題

1. 場景復(fù)現(xiàn)

我們使用的protostuff依賴如下

 <dependency>
    <groupId>com.dyuproject.protostuff</groupId>
    <artifactId>protostuff-core</artifactId>
    <version>1.1.3</version>
</dependency>
<dependency>
    <groupId>com.dyuproject.protostuff</groupId>
    <artifactId>protostuff-runtime</artifactId>
    <version>1.1.3</version>
</dependency>

寫一個(gè)簡單測試demo,如下

public static byte[] serialize(Object obj) {
    Schema schema = RuntimeSchema.getSchema(obj.getClass());
    LinkedBuffer buffer = LinkedBuffer.allocate(1048576);
    byte[] protoStuff;
    try {
        protoStuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
    } catch (Exception var8) {
        throw new RuntimeException("Failed to serializer");
    } finally {
        buffer.clear();
    }
    return protoStuff;
}
public static <T> T deserialize(byte[] paramArrayOfByte, Class<T> targetClass) {
    if (paramArrayOfByte != null && paramArrayOfByte.length != 0) {
        Schema<T> schema = RuntimeSchema.getSchema(targetClass);
        T instance = schema.newMessage();
        ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);
        return instance;
    } else {
        throw new RuntimeException("Failed to deserialize");
    }
}
@Test
public void testSer() {
    byte[] ans = serialize(new BigDecimal(20));
    byte[] ans2 = serialize(new BigDecimal(120));
    System.out.println(new String(ans));
    System.out.println(new String(ans2));
    BigDecimal res = deserialize(ans, BigDecimal.class);
    System.out.println(res);
}

執(zhí)行如下

ProtoStuff不支持BigDecimal序列化及反序列化怎么解決

2. 疑似原因與兼容方法

并沒有找到具體的原因,在github上有一個(gè)issure: github.com/protostuff/&hellip;,其中回復(fù)為

Protostuff works on user-defined types (pojos), not on built-in jdk types.

上面的說法是ProtoStuff更多的是用于簡單對象的序列化,而不是基礎(chǔ)的jdk類型,因此推薦的是序列一個(gè)成員變量為BigDecimal的對象

接下來我們試一下,定義一個(gè)簡單的對象,成員為BigDecimal的場景

@Data
public static class InnerDecimal {
    private BigDecimal decimal;
    public InnerDecimal() {
    }
    public InnerDecimal(BigDecimal decimal) {
        this.decimal = decimal;
    }
}
@Test
public void testSer() {
    byte[] ans = serialize(new InnerDecimal(new BigDecimal(20.123)));
    byte[] ans2 = serialize(new InnerDecimal(new BigDecimal(120.1970824)));
    System.out.println(new String(ans));
    System.out.println(new String(ans2));
    InnerDecimal res = deserialize(ans, InnerDecimal.class);
    System.out.println(res);
}

測試輸出如下

ProtoStuff不支持BigDecimal序列化及反序列化怎么解決

上面雖然可以正常工作,但與我們希望的差別有點(diǎn)大,序列化一個(gè)BigDecimal,還需要定義一個(gè)POJO包裝他,有點(diǎn)麻煩;

于是一個(gè)猥瑣的方法就是在序列化和反序列化的時(shí)候,針對BigDeimal進(jìn)行特殊處理

public static byte[] serialize(Object obj) {
    if (obj instanceof BigDecimal) {
        obj = ((BigDecimal) obj).toPlainString();
    }
    Schema schema = RuntimeSchema.getSchema(obj.getClass());
    LinkedBuffer buffer = LinkedBuffer.allocate(1048576);
    byte[] protoStuff;
    try {
        protoStuff = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
    } catch (Exception var8) {
        throw new RuntimeException("Failed to serializer");
    } finally {
        buffer.clear();
    }
    return protoStuff;
}
public static <T> T deserialize(byte[] paramArrayOfByte, Class<T> targetClass) {
    if (paramArrayOfByte != null && paramArrayOfByte.length != 0) {
        Schema schema;
        if (targetClass.isAssignableFrom(BigDecimal.class)) {
            schema = RuntimeSchema.getSchema(String.class);
            Object instance = schema.newMessage();
            ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);
            return (T) new BigDecimal((String) instance);
        } else {
            schema = RuntimeSchema.getSchema(targetClass);
            Object instance = schema.newMessage();
            ProtostuffIOUtil.mergeFrom(paramArrayOfByte, instance, schema);
            return (T) instance;
        }
    } else {
        throw new RuntimeException("Failed to deserialize");
    }
}

再次測試,正常執(zhí)行

ProtoStuff不支持BigDecimal序列化及反序列化怎么解決

“ProtoStuff不支持BigDecimal序列化及反序列化怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI