如果我将POJO序列化为二进制格式以区分float和double,例如Smile或CBOR,是否有一种使用序列化类型反序列化为Map的简单方法?例如:
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
}
}
如果我检查jack.cbor,我可以清楚地看到权重字段被序列化为单精度浮点数:
$ 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
如何让readValue()将类型保留为序列化?
答案 0 :(得分:0)
我还没有想到CBOR,但这就是我想出的微笑。我将以下内部类添加到SimpleJacksonTest(以及必需的导入):
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);
}
}
然后我将它合并到映射器中,如下所示:
SimpleModule module = new SimpleModule();
module.addDeserializer(Number.class, new SmileNumberDeserializer());
mapper.registerModule(module);
现在以下断言成功:
assertEquals(Float.class, jill.get("weight").getClass());
这完全取决于保留类型的反序列化器,因此getNumberType()返回NumberType.FLOAT。