Skip to content

Commit

Permalink
Correct retrieving deserializer / serializer from the bean context (#859
Browse files Browse the repository at this point in the history
)
  • Loading branch information
dstepanov authored Jun 20, 2024
1 parent 43e03c3 commit 3e6e150
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
import io.micronaut.core.type.Argument;
import io.micronaut.inject.ArgumentInjectionPoint;
import io.micronaut.inject.InjectionPoint;
import io.micronaut.serde.Deserializer;
import io.micronaut.serde.Serde;
import io.micronaut.serde.SerdeIntrospections;
import io.micronaut.serde.Serializer;
import io.micronaut.serde.config.DeserializationConfiguration;
import io.micronaut.serde.config.SerdeConfiguration;
import io.micronaut.serde.config.SerializationConfiguration;
import io.micronaut.serde.exceptions.SerdeException;
import io.micronaut.serde.support.deserializers.ObjectDeserializer;
import io.micronaut.serde.support.deserializers.SerdeDeserializationPreInstantiateCallback;
import io.micronaut.serde.support.serdes.InetAddressSerde;
Expand Down Expand Up @@ -69,6 +72,32 @@ <S extends Serde<T>, T> S provideSerde(InjectionPoint<Serde<T>> serdeInjectionPo
return null;
}

@Any
@Prototype
@BootstrapContextCompatible
<S extends Deserializer<T>, T> S provideDeserializer(InjectionPoint<Deserializer<T>> injectionPoint,
BeanProvider<DefaultSerdeRegistry> serdeRegistry) throws SerdeException {
if (injectionPoint instanceof ArgumentInjectionPoint<?, ?> argumentInjectionPoint) {
Argument typeParameter = argumentInjectionPoint.getArgument().getTypeParameters()[0];
DefaultSerdeRegistry defaultSerdeRegistry = serdeRegistry.get();
return (S) defaultSerdeRegistry.findDeserializer(typeParameter);
}
return null;
}

@Any
@Prototype
@BootstrapContextCompatible
<S extends Serializer<T>, T> S provideSerializer(InjectionPoint<Serializer<T>> injectionPoint,
BeanProvider<DefaultSerdeRegistry> serdeRegistry) throws SerdeException {
if (injectionPoint instanceof ArgumentInjectionPoint<?, ?> argumentInjectionPoint) {
Argument typeParameter = argumentInjectionPoint.getArgument().getTypeParameters()[0];
DefaultSerdeRegistry defaultSerdeRegistry = serdeRegistry.get();
return (S) defaultSerdeRegistry.findSerializer(typeParameter);
}
return null;
}

@Singleton
@BootstrapContextCompatible
ObjectSerializer provideObjectSerializer(BeanContext beanContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ package io.micronaut.serde.support.serdes

import io.micronaut.context.BeanContext
import io.micronaut.core.type.Argument
import io.micronaut.json.JsonMapper
import io.micronaut.serde.Deserializer
import io.micronaut.serde.LimitingStream
import io.micronaut.serde.Serde
import io.micronaut.serde.SerdeRegistry
import io.micronaut.serde.Serializer
import io.micronaut.serde.support.deserializers.ObjectDeserializer
import io.micronaut.serde.support.serializers.ObjectSerializer
import io.micronaut.serde.support.util.JsonNodeDecoder
import io.micronaut.serde.support.util.JsonNodeEncoder
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification
Expand Down Expand Up @@ -71,5 +78,30 @@ class BeanContextSerdeSpec extends Specification {
enumSerde.getClass() == EnumSerde
}

void "test retrieving Map serializer / deserializer"() {
when:
def value = Map.of("name", "Denis")
def serdeRegistry = beanContext.getBean(SerdeRegistry)
def jsonMapper = beanContext.getBean(JsonMapper)
def encoderContext = serdeRegistry.newEncoderContext(null)
def decoderContext = serdeRegistry.newDecoderContext(null)
def argument = Argument.mapOf(String, Object)
def serializer = beanContext.getBean(Argument.of(Serializer, argument)).createSpecific(encoderContext, argument)
def deserializer = beanContext.getBean(Argument.of(Deserializer, argument)).createSpecific(decoderContext, argument)
def encoder = JsonNodeEncoder.create()

then:
serializer.serialize(encoder, encoderContext, argument, value)
def jsonNode = encoder.getCompletedValue()
def str = jsonMapper.writeValueAsString(jsonNode)
then:
str == '{"name":"Denis"}'
when:
def decoder = JsonNodeDecoder.create(jsonNode, LimitingStream.DEFAULT_LIMITS)
def deserResult = deserializer.deserialize(decoder, decoderContext, argument)
then:
deserResult == value
}

static enum MyEnum {}
}

0 comments on commit 3e6e150

Please sign in to comment.