Prevent using NestedEntitySerializer if target serializer does not support unwrapping.
We now verify that the serializer registered for the type that's supposed to be handled by the NestedEntitySerializer actually supports unwrapping as the serialization in EntityModel (MapSuppressingUnwrappingSerializer) requires that to work properly. Fixes #2056.
This commit is contained in:
@@ -406,6 +406,12 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
return value;
|
||||
}
|
||||
|
||||
JsonSerializer<Object> unwrappingSerializer = serializer.unwrappingSerializer(NameTransformer.NOP);
|
||||
|
||||
if (!unwrappingSerializer.isUnwrappingSerializer()) {
|
||||
return value;
|
||||
}
|
||||
|
||||
PersistentEntity<?, ?> entity = entities.getRequiredPersistentEntity(value.getClass());
|
||||
|
||||
return invoker.invokeProcessorsFor(PersistentEntityResource.build(value, entity).//
|
||||
|
||||
@@ -46,12 +46,14 @@ import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||
import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.rest.core.support.SelfLinkProvider;
|
||||
import org.springframework.data.rest.webmvc.EmbeddedResourcesAssembler;
|
||||
import org.springframework.data.rest.webmvc.PersistentEntityResource;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.AssociationOmittingSerializerModifier;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.AssociationUriResolvingDeserializerModifier;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.LookupObjectSerializer;
|
||||
import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module.NestedEntitySerializer;
|
||||
import org.springframework.data.rest.webmvc.mapping.Associations;
|
||||
import org.springframework.data.rest.webmvc.support.ExcerptProjector;
|
||||
import org.springframework.hateoas.EntityModel;
|
||||
import org.springframework.hateoas.UriTemplate;
|
||||
import org.springframework.hateoas.server.EntityLinks;
|
||||
import org.springframework.hateoas.server.mvc.RepresentationModelProcessorInvoker;
|
||||
@@ -62,8 +64,11 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
|
||||
/**
|
||||
@@ -95,6 +100,7 @@ class PersistentEntityJackson2ModuleUnitTests {
|
||||
mappingContext.getPersistentEntity(PersistentEntityJackson2ModuleUnitTests.PetOwner.class);
|
||||
mappingContext.getPersistentEntity(Immutable.class);
|
||||
mappingContext.getPersistentEntity(Wrapper.class);
|
||||
mappingContext.getPersistentEntity(Surrounding.class);
|
||||
|
||||
this.persistentEntities = new PersistentEntities(Arrays.asList(mappingContext));
|
||||
|
||||
@@ -102,12 +108,13 @@ class PersistentEntityJackson2ModuleUnitTests {
|
||||
|
||||
NestedEntitySerializer nestedEntitySerializer = new NestedEntitySerializer(persistentEntities,
|
||||
new EmbeddedResourcesAssembler(persistentEntities, associations, mock(ExcerptProjector.class)), invoker);
|
||||
SimpleModule module = new SimpleModule();
|
||||
|
||||
SimpleModule module = new SimpleModule();
|
||||
module.setSerializerModifier(new AssociationOmittingSerializerModifier(persistentEntities, associations,
|
||||
nestedEntitySerializer, new LookupObjectSerializer(PluginRegistry.of(new HomeLookup()))));
|
||||
module.setDeserializerModifier(
|
||||
new AssociationUriResolvingDeserializerModifier(persistentEntities, associations, converter, factory));
|
||||
module.addSerializer(new CustomTypeSerializer());
|
||||
|
||||
this.mapper = new ObjectMapper();
|
||||
this.mapper.registerModule(module);
|
||||
@@ -213,6 +220,14 @@ class PersistentEntityJackson2ModuleUnitTests {
|
||||
assertThat(mapper.writeValueAsString(wrapper)).isEqualTo("{\"value\":\"sample\"}");
|
||||
}
|
||||
|
||||
@Test // GH-2056
|
||||
void doesNotWrapValuesWithoutUnwrappingSerializer() {
|
||||
|
||||
EntityModel<Surrounding> model = PersistentEntityResource.of(new Surrounding());
|
||||
|
||||
assertThatNoException().isThrownBy(() -> mapper.writeValueAsString(model));
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@@ -284,4 +299,35 @@ class PersistentEntityJackson2ModuleUnitTests {
|
||||
static class ValueType {
|
||||
@JsonValue String value;
|
||||
}
|
||||
|
||||
// GH-2056
|
||||
|
||||
@Data
|
||||
static class Surrounding {
|
||||
CustomType custom = new CustomType();
|
||||
}
|
||||
|
||||
static class CustomType {}
|
||||
|
||||
static class CustomTypeSerializer extends StdSerializer<CustomType> {
|
||||
|
||||
private static final long serialVersionUID = -3841651446883968079L;
|
||||
|
||||
public CustomTypeSerializer() {
|
||||
super(CustomType.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.fasterxml.jackson.databind.ser.std.StdSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
|
||||
*/
|
||||
@Override
|
||||
public void serialize(CustomType value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
|
||||
gen.writeStartObject();
|
||||
gen.writeFieldName("foo");
|
||||
gen.writeString("bar");
|
||||
gen.writeEndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user