ProtoStuff unterstützt keine BigDecimal-Serialisierung/Deserialisierung?

Arbeiten Sie zusammen, um gemeinsam zu schaffen und zu wachsen! Dies ist der 12. Tag meiner Teilnahme an der „Nuggets Daily New Plan·August Update Challenge“, klicken Sie hier, um die Details der Veranstaltung anzuzeigen

Normalerweise verwende ich ProtoStuff als Serialisierungstool, um einige POJO-Objekte zu serialisieren, aber in der Praxis stellt sich heraus, dass es Probleme beim Serialisieren von BigDecimal-Objekten gibt

  • Unabhängig von der Zahl ist das resultierende Byte-Array dasselbe
  • Kann nicht richtig deserialisieren

Notieren Sie dieses Problem unten

1. Szenenwiedergabe

Die Protostuff-Abhängigkeiten, die wir verwenden, sind wie folgt

 <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>
复制代码

Schreiben Sie wie folgt eine einfache Testdemo

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);
}
复制代码

Führen Sie wie folgt aus

2. Vermutete Ursachen und kompatible Methoden

Ich habe keinen bestimmten Grund gefunden, es gibt ein Problem auf Github: github.com/protostuff/… , wo die Antwort ist

Protostuff funktioniert mit benutzerdefinierten Typen (Pojos), nicht mit integrierten JDK-Typen.

Die obige Aussage ist, dass ProtoStuff eher für die Serialisierung einfacher Objekte gedacht ist, nicht für den grundlegenden jdk-Typ, daher wird empfohlen, ein Objekt zu serialisieren, dessen Mitgliedsvariable BigDecimal ist

Probieren wir es als Nächstes aus, definieren Sie ein einfaches Objekt mit einem BigDecimal-Member

@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);
}
复制代码

Die Testausgabe ist wie folgt

Obwohl das obige normal funktionieren kann, ist es ein wenig anders als wir gehofft haben. Um ein BigDecimal zu serialisieren, ist es notwendig, ein POJO zu definieren, um es zu umschließen, was ein bisschen mühsam ist; also ist es eine obszöne Methode, Serialisierung und Deserialisierung für durchzuführen BigDeimal.Sonderbehandlung

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");
    }
}
复制代码

Testen Sie erneut, normale Ausführung

Aussage

Es ist nicht so gut wie ein Glaubensbekenntnis. Der Inhalt wurde bereits geschrieben, und es stammt rein von der Familie. Aufgrund begrenzter persönlicher Fähigkeiten ist es unvermeidlich, dass es zu Auslassungen und Fehlern kommt. Wenn Sie Fehler finden oder besser haben Vorschläge können Sie gerne kritisieren und korrigieren

  • QQ: Ein Graugrau / 3302797840
  • Öffentliche Nummer: ein grauer Blog
  • Eine graue Seite: hhui.top

Ich denke du magst

Origin juejin.im/post/7133583979667521544
Empfohlen
Rangfolge