本篇内容介绍了“ProtoStuff不支持BigDecimal序列化及反序列化怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
平时使用ProtoStuff作为序列化工具,对于一些POJO对象序列化,但是在实际使用中,发现针对BigDecimal对象进行序列化时却出现了问题
不管什么数,生成的byte数组都一样
无法正确反序列化
下面记录一下这个问题
我们使用的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); }
执行如下
并没有找到具体的原因,在github上有一个issure: github.com/protostuff/…,其中回复为
Protostuff works on user-defined types (pojos), not on built-in jdk types.
上面的说法是ProtoStuff更多的是用于简单对象的序列化,而不是基础的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); }
测试输出如下
上面虽然可以正常工作,但与我们希望的差别有点大,序列化一个BigDecimal,还需要定义一个POJO包装他,有点麻烦;
于是一个猥琐的方法就是在序列化和反序列化的时候,针对BigDeimal进行特殊处理
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"); } }
再次测试,正常执行
“ProtoStuff不支持BigDecimal序列化及反序列化怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。