DATAREST-326 - Improved configuration setup for better Boot compatibility.
We now don't expose the PersistentEntityJackson2Module as bean anymore to prevent global registration in case of a Boot setup. The HttpMessageConverters registered are now TypeConstrainedMappingJackson2HttpMessageConverters so that they only get used of the object to marshal is of type ResourceSupport.
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<spring.hateoas>0.15.0.RELEASE</spring.hateoas>
|
||||
<spring.hateoas>0.16.0.BUILD-SNAPSHOT</spring.hateoas>
|
||||
<springplugin>1.1.0.RELEASE</springplugin>
|
||||
<evoinflector>1.2</evoinflector>
|
||||
</properties>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
@@ -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<MappingJackson2HttpMessageConverter> converters = context.getBeansOfType(
|
||||
MappingJackson2HttpMessageConverter.class).values();
|
||||
|
||||
for (HttpMessageConverter<?> converter : converters) {
|
||||
assertThat(converter, is(instanceOf(TypeConstrainedMappingJackson2HttpMessageConverter.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ExtendingConfiguration extends RepositoryRestMvcConfiguration {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user