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