Hi Johan, Thanks for your thoughts. Are you able to elaborate a little more?
> Whenever you serialize and say “Hey’ let’s use polymorphism", you are pretty > much bound to fail. I’m not sure why you say this. I thought that by including the schema information, that is exactly what we were avoiding… I’m not sure I’m getting your idea about the command pattern. Would you mind showing me a quick example? Cheers, =David > On Aug 21, 2016, at 2:42 PM, Johan Edstrom <[email protected]> wrote: > > Whenever you serialize and say “Hey’ let’s use polymorphism", you are pretty > much bound to fail. > > Use something like a command pattern identifying what you are doing > so you can pick the de-serializer. > > > >> On Aug 20, 2016, at 11:32 PM, David Leangen <[email protected]> wrote: >> >> >> I had a few thoughts about this topic. >> >> In order to properly deserialise, we would need the schema. Since the DTO >> type *is* the schema, then somehow the schema needs to be serialised as >> well, or at least known upon serialisation. >> >> If the API were to have a toSchema() method, that would simplify things a >> lot. A client should also be able to do something like this: >> >> SomeDTO dto = ... >> codec.encode( dto ).serializeTo( out ); >> >> Or maybe: >> >> codec.withSchema( SomeDTO.class).encode( dto ).to( out ); >> >> The SomeDTO schema would also be serialised (perhaps simply using the >> fully-qualified class name as an alias?), so then the client could do this: >> >> Object o = codec.deserializeFrom( in ) >> >> Since the schema is included in the input data, the serializer will behind >> the scene do something like: >> >> >> Map<String, Object> map = codec.decode( Map.class ).from( in ); >> // Get the schema type, which is SomeDTO.class >> ... >> Object o = converter.convert( map.get(“data”) ).to( SomeDTO.class ); >> >> >> wdyt? >> >> =David >> >> >> >>> On Aug 20, 2016, at 3:23 PM, David Leangen <[email protected]> wrote: >>> >>> >>> Hi, >>> >>> I am trying to use the Convert/Codec as a serializer, but it has been a bit >>> of a struggle so far. >>> >>> I have a “deep” object structure (i.e. at least one level of embedded >>> objects). Writing the data as a JSON string works just fine. However, when >>> deserialising, I am having trouble. The data object uses generics, so it is >>> not possible to determine the type at runtime. My embedded objects end up >>> being deserialised as Maps, which of course causes a ClassCastException >>> later on in the code. >>> >>> I have tried adding a Rule using an adapter, and setting the >>> codec.with(thatAdapter), but that didn’t work out so well, either. >>> >>> Here is an example of my attempt so far. I am working with Prevayler, so I >>> need to serialize/deserialze a command object, which contains some data. >>> >>> I think that this code _should_ work, which means that there is likely a >>> bug in the code. Even so… >>> >>> This is a very convoluted way of working, which doesn’t seem right to me. >>> Am I missing some concept? >>> >>> >>> Example below. >>> >>> Cheers, >>> =David >>> >>> >>> public class DTOSerializer<E> >>> implements Serializer // This is the interface provided by Prevayler >>> { >>> private final Converter converter; >>> private final Codec codec; >>> private final Class<E> type; >>> >>> public DTOSerializer( Converter aConverter, Codec aCodec, Class<E> aType ) >>> { >>> // Very convoluted attempt at adding a rule to try to make the >>> conversion of my “PutCommand” work during deserialization >>> converter = aConverter.getAdapter() >>> .rule( >>> PutCommand.class, >>> Map.class, >>> dto -> { Map map = new HashMap<>(); map.put( "key", >>> dto.key ); map.put( "entity", dto.entity ); return map; }, >>> map -> { PutCommand c = new PutCommand(); c.key = >>> (String)map.get( "key" ); c.entity = aConverter.convert( map.get( "entity" >>> ) ).to( aType ); return c; } ); >>> codec = aCodec.with( converter ); >>> } >>> >>> @Override >>> public Object readObject( InputStream in ) >>> throws Exception >>> { >>> // This is the raw data >>> final Map<String, Object> map = codec.decode( Map.class ).from( in ); >>> // The name of the object type to cast to >>> final String commandTypeName = (String)map.get( "command" ); >>> final Class<?> commandType = Class.forName( commandTypeName ); >>> // This indeed returns an object of the correct type, >>> // HOWEVER, the embedded objects are not of the correct type, they are >>> of type Map >>> final Object command = converter.convert( map.get( "payload" ) ).to( >>> commandType ); >>> return command; >>> } >>> >>> @Override >>> public void writeObject( OutputStream out, Object object ) >>> throws Exception >>> { >>> final Map<String, Object> map = new HashMap<>(); >>> // Serialize the name of the command so I know what to cast it do when >>> deserializing >>> map.put( "command", object.getClass().getName() ); >>> // This is the actual payload, which is nothing more than the command >>> object >>> map.put( "payload", object ); >>> codec.encode( map ).to( out ); >>> } >>> } >>> >> >
