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 );
>>   }
>> }
>> 
> 

Reply via email to