diff --git a/spring-data-rest-core/pom.xml b/spring-data-rest-core/pom.xml
index 19acbc889..1b358e514 100644
--- a/spring-data-rest-core/pom.xml
+++ b/spring-data-rest-core/pom.xml
@@ -16,7 +16,7 @@
- 0.15.0.RELEASE
+ 0.16.0.BUILD-SNAPSHOT
1.1.0.RELEASE
1.2
diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/PersistentEntityResourceHandlerMethodArgumentResolver.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/PersistentEntityResourceHandlerMethodArgumentResolver.java
index 395cc7afc..742d61ada 100644
--- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/PersistentEntityResourceHandlerMethodArgumentResolver.java
+++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/PersistentEntityResourceHandlerMethodArgumentResolver.java
@@ -115,7 +115,7 @@ public class PersistentEntityResourceHandlerMethodArgumentResolver implements Ha
for (HttpMessageConverter converter : messageConverters) {
- if (!converter.canRead(domainType, contentType)) {
+ if (!converter.canRead(PersistentEntityResource.class, contentType)) {
continue;
}
diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java
index f1d0da8fa..0ba00fdba 100644
--- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java
+++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java
@@ -98,12 +98,14 @@ import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.RelProvider;
import org.springframework.hateoas.ResourceProcessor;
+import org.springframework.hateoas.ResourceSupport;
import org.springframework.hateoas.config.EnableHypermediaSupport;
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
import org.springframework.hateoas.core.EvoInflectorRelProvider;
import org.springframework.hateoas.hal.CurieProvider;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.hateoas.hal.Jackson2HalModule.HalHandlerInstantiator;
+import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@@ -373,7 +375,11 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
*/
@Bean
public ObjectMapper objectMapper() {
- return basicObjectMapper();
+
+ ObjectMapper mapper = basicObjectMapper();
+ mapper.registerModule(persistentEntityJackson2Module());
+
+ return mapper;
}
/**
@@ -394,7 +400,8 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
mediaTypes.add(MediaType.APPLICATION_JSON);
}
- MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
+ MappingJackson2HttpMessageConverter jacksonConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(
+ ResourceSupport.class);
jacksonConverter.setObjectMapper(objectMapper());
jacksonConverter.setSupportedMediaTypes(mediaTypes);
@@ -416,7 +423,8 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
mediaTypes.add(MediaType.APPLICATION_JSON);
}
- MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
+ MappingJackson2HttpMessageConverter converter = new TypeConstrainedMappingJackson2HttpMessageConverter(
+ ResourceSupport.class);
converter.setObjectMapper(halObjectMapper());
converter.setSupportedMediaTypes(mediaTypes);
@@ -429,6 +437,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
HalHandlerInstantiator instantiator = new HalHandlerInstantiator(getDefaultedRelProvider(), curieProvider);
ObjectMapper mapper = basicObjectMapper();
+ mapper.registerModule(persistentEntityJackson2Module());
mapper.registerModule(new Jackson2HalModule());
mapper.setHandlerInstantiator(instantiator);
@@ -508,8 +517,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
*
* @return
*/
- @Bean
- public Module persistentEntityJackson2Module() {
+ private Module persistentEntityJackson2Module() {
return new PersistentEntityJackson2Module(resourceMappings(), persistentEntities(), config(),
uriToEntityConverter());
}
@@ -555,6 +563,10 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
messageConverters.add(halJacksonHttpMessageConverter());
}
+ MappingJackson2HttpMessageConverter fallbackJsonConverter = new MappingJackson2HttpMessageConverter();
+ fallbackJsonConverter.setObjectMapper(basicObjectMapper());
+
+ messageConverters.add(fallbackJsonConverter);
messageConverters.add(uriListHttpMessageConverter());
return messageConverters;
@@ -622,12 +634,12 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon
private ObjectMapper basicObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
+
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
- // Our special PersistentEntityResource Module
- objectMapper.registerModule(persistentEntityJackson2Module());
- objectMapper.registerModule(geoModule);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+ objectMapper.registerModule(geoModule);
Jackson2DatatypeHelper.configureObjectMapper(objectMapper);
// Configure custom Modules
configureJacksonObjectMapper(objectMapper);
diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java
index 7bdef8ddd..c3f7edc44 100644
--- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java
+++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java
@@ -380,7 +380,7 @@ public abstract class AbstractWebIntegrationTests {
public void servesHalWhenJsonIsRequested() throws Exception {
mvc.perform(get("/").accept(MediaType.APPLICATION_JSON)). //
- andExpect(content().contentType(MediaType.APPLICATION_JSON)). //
+ andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)). //
andExpect(jsonPath("$._links", notNullValue()));
}
diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java
index f1b23b847..3a23a190d 100644
--- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java
+++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvConfigurationIntegrationTests.java
@@ -18,12 +18,14 @@ package org.springframework.data.rest.webmvc.config;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
+import java.util.Collection;
import java.util.Date;
import java.util.Locale;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -32,13 +34,16 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.RepositoryLinksResource;
+import org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module;
import org.springframework.data.web.HateoasPageableHandlerMethodArgumentResolver;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.hateoas.LinkDiscoverers;
import org.springframework.hateoas.core.DefaultRelProvider;
+import org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
@@ -127,6 +132,28 @@ public class RepositoryRestMvConfigurationIntegrationTests {
assertThat(result, is((Object) formatter.print(sample.date, Locale.US)));
}
+ /**
+ * @see DATAREST-362
+ */
+ @Test(expected = NoSuchBeanDefinitionException.class)
+ public void doesNotExposePersistentEntityJackson2ModuleAsBean() {
+ context.getBean(PersistentEntityJackson2Module.class);
+ }
+
+ /**
+ * @see DATAREST-362
+ */
+ @Test
+ public void registeredHttpMessageConvertersAreTypeConstrained() {
+
+ Collection converters = context.getBeansOfType(
+ MappingJackson2HttpMessageConverter.class).values();
+
+ for (HttpMessageConverter> converter : converters) {
+ assertThat(converter, is(instanceOf(TypeConstrainedMappingJackson2HttpMessageConverter.class)));
+ }
+ }
+
@Configuration
static class ExtendingConfiguration extends RepositoryRestMvcConfiguration {