Now i'm working with Jackson and i have some questions about it.
First of all. I have two services, first is data collecting and sending service and second receive this data and, for example, log it into a file.
So, first service has class hierarchy like this:
+----ConcreteC | Base ----+----ConcreteA | +----ConcreteB
And second service has class hierarchy like this:
ConcreteAAdapter extends ConcreteA implements Adapter {} ConcreteBAdapter extends ConcreteB implements Adapter {} ConcreteCAdapter extends ConcreteC implements Adapter {}
The first service knows nothing about ConcreteXAdapter
.
The way i'm sending the data on the first service:
Collection<Base> data = new LinkedBlockingQueue<Base>() JacksonUtils utils = new JacksonUtils(); data.add(new ConcreteA()); data.add(new ConcreteB()); data.add(new ConcreteC()); ... send(utils.marshall(data)); ... public class JacksonUtils { public byte[] marshall(Collection<Base> data) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream() { @Override public byte[] toByteArray() { return buf; } }; getObjectMapper().writeValue(out, data); return out.toByteArray(); } protected ObjectMapper getObjectMapper() { return new ObjectMapper(); } public Object unmarshall(byte[] json) throws IOException { return getObjectMapper().readValue(json, Object.class); } public <T> T unmarshall(InputStream source, TypeReference<T> typeReference) throws IOException { return getObjectMapper().readValue(source, typeReference); } public <T> T unmarshall(byte[] json, TypeReference<T> typeReference) throws IOException { return getObjectMapper().readValue(json, typeReference); } }
So, i want to desirialize json into Collection of ConcreteXAdapter
, not into Collection of ConcreteX
(ConcreteA -> ConcreteAAdapter, ConcreteB -> ConcreteBAdapter, ConcreteC -> ConcreteCAdapter
). In the case i described i want to get:
Collection [ConcreteAAdapter, ConcreteBAdapter, ConcreteCAdapter]
How can i do this?
A JsonNode is Jackson's tree model for JSON and it can read JSON into a JsonNode instance and write a JsonNode out to JSON. To read JSON into a JsonNode with Jackson by creating ObjectMapper instance and call the readValue() method. We can access a field, array or nested object using the get() method of JsonNode class.
How to deserialize Date from JSON using Jackson. In order to correct deserialize a Date field, you need to do two things: 1) Create a custom deserializer by extending StdDeserializer<T> class and override its deserialize(JsonParser jsonparser, DeserializationContext context) method.
databind. ObjectMapper ) is the simplest way to parse JSON with Jackson. The Jackson ObjectMapper can parse JSON from a string, stream or file, and create a Java object or object graph representing the parsed JSON. Parsing JSON into Java objects is also referred to as to deserialize Java objects from JSON.
For this purpose you need to pass additional info in JSON:
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="@type") class Base { ... }
Then on serialization it will add @type field:
objectMapper.registerSubtypes( new NamedType(ConcreteAAdapter.class, "ConcreteA"), new NamedType(ConcreteBAdapter.class, "ConcreteB"), new NamedType(ConcreteCAdapter.class, "ConcreteC") ); // note, that for lists you need to pass TypeReference explicitly objectMapper.writerWithType(new TypeReference<List<Base>>() {}) .writeValueAsString(someList); { "@type" : "ConcreteA", ... }
on deserialization it will be:
objectMapper.registerSubtypes( new NamedType(ConcreteA.class, "ConcreteA"), new NamedType(ConcreteB.class, "ConcreteB"), new NamedType(ConcreteC.class, "ConcreteC") ); objectMapper.readValue(....)
More info here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With