DATAREST-697 - Fixed unwrapping mode in ProjectionSerializer.

Projection serializer now only creates a nested JSON document if it's not in unwrapping mode. Switched to a completely immutable implementation as we were previously mutating state in the request for an unwrapping instance as we were assuming the instances not being reused.
This commit is contained in:
Oliver Gierke
2015-12-10 13:20:47 +01:00
parent 66f0a6d9f2
commit f7cff01d99
2 changed files with 43 additions and 7 deletions

View File

@@ -434,19 +434,33 @@ public class PersistentEntityJackson2Module extends SimpleModule {
private final LinkCollector collector;
private final ResourceMappings mappings;
private boolean unwrapping;
private final boolean unwrapping;
/**
* Creates a new {@link ProjectionSerializer} for the given {@link LinkCollector}.
* Creates a new {@link ProjectionSerializer} for the given {@link LinkCollector} and {@link ResourceMappings}.
*
* @param collector
* @param collector must not be {@literal null}.
* @param mappings must not be {@literal null}.
*/
public ProjectionSerializer(LinkCollector collector, ResourceMappings mappings) {
this(collector, mappings, false);
}
/**
* Creates a new {@link ProjectionSerializer} for the given {@link LinkCollector}, {@link ResourceMappings} whether
* to be in unwrapping mode or not.
*
* @param collector must not be {@literal null}.
* @param mappings must not be {@literal null}.
* @param unwrapping
*/
private ProjectionSerializer(LinkCollector collector, ResourceMappings mappings, boolean unwrapping) {
super(TargetAware.class);
this.collector = collector;
this.mappings = mappings;
this.unwrapping = unwrapping;
}
/*
@@ -461,14 +475,18 @@ public class PersistentEntityJackson2Module extends SimpleModule {
Links links = mappings.getMetadataFor(value.getTargetClass()).isExported() ? collector.getLinksFor(target)
: new Links();
jgen.writeStartObject();
if (!unwrapping) {
jgen.writeStartObject();
}
provider.//
findValueSerializer(ProjectionResource.class, null).//
unwrappingSerializer(null).//
serialize(new ProjectionResource(value, links), jgen, provider);
jgen.writeEndObject();
if (!unwrapping) {
jgen.writeEndObject();
}
}
/*
@@ -486,8 +504,7 @@ public class PersistentEntityJackson2Module extends SimpleModule {
*/
@Override
public JsonSerializer<TargetAware> unwrappingSerializer(NameTransformer unwrapper) {
this.unwrapping = true;
return this;
return new ProjectionSerializer(collector, mappings, true);
}
}

View File

@@ -41,6 +41,7 @@ import org.springframework.data.rest.webmvc.jpa.Order;
import org.springframework.data.rest.webmvc.jpa.OrderRepository;
import org.springframework.data.rest.webmvc.jpa.Person;
import org.springframework.data.rest.webmvc.jpa.PersonRepository;
import org.springframework.data.rest.webmvc.jpa.PersonSummary;
import org.springframework.data.rest.webmvc.jpa.UserExcerpt;
import org.springframework.data.rest.webmvc.mongodb.Address;
import org.springframework.data.rest.webmvc.mongodb.User;
@@ -50,6 +51,7 @@ import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkDiscoverer;
import org.springframework.hateoas.PagedResources;
import org.springframework.hateoas.PagedResources.PageMetadata;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.core.EmbeddedWrapper;
import org.springframework.hateoas.core.EmbeddedWrappers;
import org.springframework.hateoas.hal.HalLinkDiscoverer;
@@ -304,4 +306,21 @@ public class PersistentEntitySerializationTests {
public void deserializesTranslatedEnumProperty() throws Exception {
assertThat(mapper.readValue("{ \"gender\" : \"Male\" }", User.class).gender, is(Gender.MALE));
}
/**
* @see DATAREST-697
*/
@Test
public void rendersProjectionWithinSimpleResourceCorrectly() throws Exception {
Person person = new Person("Dave", "Matthews");
person.setId(1L);
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
PersonSummary projection = factory.createProjection(PersonSummary.class, person);
String result = mapper.writeValueAsString(new Resource<PersonSummary>(projection));
assertThat(JsonPath.read(result, "$._links.self"), is(notNullValue()));
}
}