ProtoStuff不支持BigDecimal序列化及反序列化詳解
引言
平時使用ProtoStuff作為序列化工具,對于一些POJO對象序列化,但是在實際使用中,發(fā)現(xiàn)針對BigDecimal對象進(jìn)行序列化時卻出現(xiàn)了問題
- 不管什么數(shù),生成的byte數(shù)組都一樣
- 無法正確反序列化
下面記錄一下這個問題
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>
寫一個簡單測試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í)行如下
2. 疑似原因與兼容方法
并沒有找到具體的原因,在github上有一個issure: github.com/protostuff/…,其中回復(fù)為
Protostuff works on user-defined types (pojos), not on built-in jdk types.
上面的說法是ProtoStuff更多的是用于簡單對象的序列化,而不是基礎(chǔ)的jdk類型,因此推薦的是序列一個成員變量為BigDecimal的對象
接下來我們試一下,定義一個簡單的對象,成員為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); }
測試輸出如下
上面雖然可以正常工作,但與我們希望的差別有點(diǎn)大,序列化一個BigDecimal,還需要定義一個POJO包裝他,有點(diǎn)麻煩;
于是一個猥瑣的方法就是在序列化和反序列化的時候,針對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序列化及反序列化詳解的詳細(xì)內(nèi)容,更多關(guān)于ProtoStuff不支持BigDecimal的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java微信公眾平臺開發(fā)(10) 微信自定義菜單的創(chuàng)建實現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺開發(fā)第十步,微信自定義菜單的創(chuàng)建實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04springboot之redis cache TTL選項的使用
這篇文章主要介紹了springboot之redis cache TTL選項的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07淺談Spring Boot 2.0遷移指南主要注意點(diǎn)
Spring官方的Spring Boot 2變動指南,主要是幫助您將應(yīng)用程序遷移到Spring Boot 2.0,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-10-10java.lang.ArrayIndexOutOfBoundsException數(shù)組越界異常問題解決
這篇文章主要給大家介紹了關(guān)于java.lang.ArrayIndexOutOfBoundsException數(shù)組越界異常問題解決的相關(guān)資料,數(shù)組越界訪問是一個非常嚴(yán)重的問題,文中通過圖文將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01spring boot中interceptor攔截器未生效的解決
這篇文章主要介紹了spring boot中interceptor攔截器未生效的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09