2016-05-13 5 views
0

Wenn ich ein POJO in ein Binärformat serialisiere, das float von double unterscheidet, wie Smile oder CBOR, gibt es eine einfache Möglichkeit zur Deserialisierung in eine Map mit dem serialisierten Typ? Zum Beispiel:Retain-Typ beim Deserialisieren aus Binärformaten wie CBOR

import java.io.*; 
import java.util.*; 

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.dataformat.cbor.CBORFactory; 

import static org.junit.Assert.*; 
import org.junit.Test; 

public class SimpleJacksonTest { 
    private float weight; 

    public SimpleJacksonTest() {} 

    public float getWeight() { 
     return weight; 
    } 

    public void setWeight(float weight) { 
     this.weight = weight; 
    } 

    @Test 
    public void TestMapFromCbor() throws IOException { 
     ObjectMapper mapper = new ObjectMapper(new CBORFactory()); 
     SimpleJacksonTest jack = new SimpleJacksonTest(); 
     jack.setWeight(123.4F); 
     mapper.writeValue(new File("jack.cbor"), jack); 

     Map<String,Object> jill = mapper.readValue(new File("jack.cbor"), Map.class); 
     assertEquals(Double.class, jill.get("weight").getClass()); // I want Float 
    } 
} 

Wenn ich jack.cbor inspizieren, kann ich deutlich sehen, dass das Gewicht Feld als einfacher Genauigkeit float serialisiert wird:

$ od -c -tx1 jack.cbor 
0000000 277 f w e i g h t 372 B 366 314 315 377 
      bf 66 77 65 69 67 68 74 fa 42 f6 cc cd ff 

Wie kann ich Readvalue() erhalten behalten der Typ als serialisiert?

+0

Ab 2.8.6 wird es funktionieren. Float wurde immer korrekt gespeichert und tokenisiert, nur von Jackson Core als Double interpretiert. Siehe https://github.com/FasterXML/jackson-dataformats-binary/issues/32 – richardstartin

Antwort

0

Ich habe es nicht für CBOR herausgefunden, aber hier ist, was ich für Smile kam. I addierten folgende inneren Klasse SimpleJacksonTest (zusammen mit den erforderlichen Importe):

private class SmileNumberDeserializer extends NumberDeserializer { 
    @Override 
    public Number deserialize(JsonParser p, DeserializationContext ctxt) 
     throws IOException 
    { 
     if (JsonTokenId.ID_NUMBER_FLOAT == p.getCurrentTokenId() 
      && NumberType.FLOAT == p.getNumberType()) { 
      return p.getFloatValue(); 
     } 
     return super.deserialize(p, ctxt); 
    } 
} 

Dann ich es in den Mapper wie folgt eingearbeitet:

SimpleModule module = new SimpleModule(); 
module.addDeserializer(Number.class, new SmileNumberDeserializer()); 
mapper.registerModule(module); 

nun folgende Behauptung folgt:

assertEquals(Float.class, jill.get("weight").getClass()); 

Dies hängt davon ab, dass der Deserializer den Typ behält, sodass getNumberType() NumberType.FLOAT zurückgibt.

Verwandte Themen