Skip to content

Commit de54531

Browse files
committed
spring-projectsGH-1926 - Avoid wrapping nested entities ultimately to represent a value.
NestedEntitySerializer now skips the wrapping into an EntityModel if the target serializer is a JsonValueSerializer as EntityModel requires the value to ultimately resolve into key value pairs as it's only enriching something that's rendered as JSON document with hypermedia elements.
1 parent 4d7daa9 commit de54531

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import com.fasterxml.jackson.databind.module.SimpleModule;
8787
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
8888
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
89+
import com.fasterxml.jackson.databind.ser.std.JsonValueSerializer;
8990
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
9091
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
9192
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -365,7 +366,7 @@ public void serialize(Object value, JsonGenerator gen, SerializerProvider provid
365366
List<Object> resources = new ArrayList<Object>();
366367

367368
for (Object element : source) {
368-
resources.add(toModel(element));
369+
resources.add(toModel(element, provider));
369370
}
370371

371372
provider.defaultSerializeValue(resources, gen);
@@ -376,13 +377,13 @@ public void serialize(Object value, JsonGenerator gen, SerializerProvider provid
376377
Map<Object, Object> resources = CollectionFactory.createApproximateMap(value.getClass(), source.size());
377378

378379
for (Entry<?, ?> entry : source.entrySet()) {
379-
resources.put(entry.getKey(), toModel(entry.getValue()));
380+
resources.put(entry.getKey(), toModel(entry.getValue(), provider));
380381
}
381382

382383
provider.defaultSerializeValue(resources, gen);
383384

384385
} else {
385-
provider.defaultSerializeValue(toModel(value), gen);
386+
provider.defaultSerializeValue(toModel(value, provider), gen);
386387
}
387388
}
388389

@@ -396,7 +397,13 @@ public void serializeWithType(Object value, JsonGenerator gen, SerializerProvide
396397
serialize(value, gen, provider);
397398
}
398399

399-
private EntityModel<Object> toModel(Object value) {
400+
private Object toModel(Object value, SerializerProvider provider) throws JsonMappingException {
401+
402+
JsonSerializer<Object> serializer = provider.findValueSerializer(value.getClass());
403+
404+
if (JsonValueSerializer.class.isInstance(serializer)) {
405+
return value;
406+
}
400407

401408
PersistentEntity<?, ?> entity = entities.getRequiredPersistentEntity(value.getClass());
402409

spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java

+24
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.mockito.ArgumentMatchers.*;
2020
import static org.mockito.Mockito.*;
2121

22+
import lombok.Data;
2223
import lombok.Getter;
2324

2425
import java.io.IOException;
@@ -58,6 +59,7 @@
5859
import com.fasterxml.jackson.annotation.JsonInclude.Include;
5960
import com.fasterxml.jackson.annotation.JsonProperty;
6061
import com.fasterxml.jackson.annotation.JsonTypeInfo;
62+
import com.fasterxml.jackson.annotation.JsonValue;
6163
import com.fasterxml.jackson.databind.ObjectMapper;
6264
import com.fasterxml.jackson.databind.module.SimpleModule;
6365
import com.jayway.jsonpath.JsonPath;
@@ -89,6 +91,7 @@ public void setUp() {
8991
mappingContext.getPersistentEntity(SampleWithAdditionalGetters.class);
9092
mappingContext.getPersistentEntity(PersistentEntityJackson2ModuleUnitTests.PetOwner.class);
9193
mappingContext.getPersistentEntity(Immutable.class);
94+
mappingContext.getPersistentEntity(Wrapper.class);
9295

9396
this.persistentEntities = new PersistentEntities(Arrays.asList(mappingContext));
9497

@@ -197,6 +200,16 @@ public void customizesDeserializerForCreatorProperties() throws Exception {
197200
TypeDescriptor.valueOf(Home.class));
198201
}
199202

203+
@Test // GH-1926
204+
public void doesNotWrapJsonValueTypesIntoEntityModel() throws Exception {
205+
206+
Wrapper wrapper = new Wrapper();
207+
wrapper.value = new ValueType();
208+
wrapper.value.value = "sample";
209+
210+
assertThat(mapper.writeValueAsString(wrapper)).isEqualTo("{\"value\":\"sample\"}");
211+
}
212+
200213
/**
201214
* @author Oliver Gierke
202215
*/
@@ -257,4 +270,15 @@ public Immutable(@JsonProperty("home") Home home) {
257270
this.home = home;
258271
}
259272
}
273+
274+
// GH-1926
275+
276+
@Data
277+
static class Wrapper {
278+
ValueType value;
279+
}
280+
281+
static class ValueType {
282+
@JsonValue String value;
283+
}
260284
}

0 commit comments

Comments
 (0)