¡Trabajar juntos para crear y crecer juntos! Este es el día 12 de mi participación en el "Nuggets Daily New Plan·August Update Challenge", haz clic para ver los detalles del evento
Usualmente uso ProtoStuff como una herramienta de serialización para serializar algunos objetos POJO, pero en el uso real, se encuentra que hay problemas al serializar objetos BigDecimal
- Independientemente del número, la matriz de bytes resultante es la misma
- No se puede deserializar correctamente
Registre este problema a continuación
1. Reproducción de escena
Las dependencias protostuff que usamos son las siguientes
<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>
复制代码
Escriba una demostración de prueba simple, de la siguiente manera
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);
}
复制代码
Ejecutar de la siguiente manera
2. Causas sospechosas y métodos compatibles
No encontré una razón específica, hay un problema en github: github.com/protostuff/… , donde la respuesta es
Protostuff funciona en tipos definidos por el usuario (pojos), no en tipos jdk incorporados.
La declaración anterior es que ProtoStuff es más para la serialización de objetos simples, no del tipo jdk básico, por lo que se recomienda serializar un objeto cuya variable miembro sea BigDecimal
A continuación, probemos, definamos un objeto simple con un miembro 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);
}
复制代码
La salida de prueba es la siguiente
Aunque lo anterior puede funcionar normalmente, es un poco diferente de lo que esperábamos.Para serializar un BigDecimal, es necesario definir un POJO para envolverlo, lo cual es un poco problemático; por lo que un método obsceno es realizar la serialización y deserialización para BigDeimal trato especial
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");
}
}
复制代码
Prueba de nuevo, ejecución normal
declaración
No es tan bueno como una carta de fe. El contenido ya ha sido escrito y es puramente de la familia. Debido a la capacidad personal limitada, es inevitable que haya omisiones y errores. Si encuentra errores o tiene mejores sugerencias, puede criticarlas y corregirlas. Gracias.
- QQ: Un gris gris / 3302797840
- Número público: un blog gris
- Un sitio gris: hhui.top