#134 - Fixed initialization of HttpMessageConverters for HAL.
The Jackson(2)ModuleRegisteringBeanPostProcessor now uses postProcess*Before*Initialization to make sure, afterPropertiesSet() has not been called on the target components which might have propagated the original HttpMessageConverters into other internal components. With this fix, adding the HttpMessageConverter for HAL is added before the call and thus will be propagated to downstream components.
This commit is contained in:
@@ -220,7 +220,7 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class Jackson2ModuleRegisteringBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
|
||||
static class Jackson2ModuleRegisteringBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
|
||||
|
||||
private CurieProvider curieProvider;
|
||||
private RelProvider relProvider;
|
||||
@@ -244,15 +244,6 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof RequestMappingHandlerAdapter) {
|
||||
|
||||
@@ -263,8 +254,8 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
if (bean instanceof AnnotationMethodHandlerAdapter) {
|
||||
|
||||
AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) bean;
|
||||
List<HttpMessageConverter<?>> augmentedConverters = potentiallyRegisterModule(Arrays
|
||||
.asList(adapter.getMessageConverters()));
|
||||
List<HttpMessageConverter<?>> augmentedConverters = potentiallyRegisterModule(Arrays.asList(adapter
|
||||
.getMessageConverters()));
|
||||
adapter
|
||||
.setMessageConverters(augmentedConverters.toArray(new HttpMessageConverter<?>[augmentedConverters.size()]));
|
||||
}
|
||||
@@ -272,6 +263,15 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
return bean;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
private List<HttpMessageConverter<?>> potentiallyRegisterModule(List<HttpMessageConverter<?>> converters) {
|
||||
|
||||
for (HttpMessageConverter<?> converter : converters) {
|
||||
@@ -333,15 +333,6 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof RequestMappingHandlerAdapter) {
|
||||
|
||||
@@ -361,6 +352,15 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
return bean;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
private List<HttpMessageConverter<?>> registerModule(List<HttpMessageConverter<?>> converters) {
|
||||
|
||||
org.codehaus.jackson.map.ObjectMapper objectMapper = new org.codehaus.jackson.map.ObjectMapper();
|
||||
|
||||
@@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
@@ -36,13 +37,17 @@ import org.springframework.hateoas.LinkDiscoverers;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.hateoas.RelProvider;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
import org.springframework.hateoas.config.HypermediaSupportBeanDefinitionRegistrar.Jackson2ModuleRegisteringBeanPostProcessor;
|
||||
import org.springframework.hateoas.core.DelegatingEntityLinks;
|
||||
import org.springframework.hateoas.core.DelegatingRelProvider;
|
||||
import org.springframework.hateoas.hal.HalLinkDiscoverer;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -106,6 +111,41 @@ public class EnableHypermediaSupportIntegrationTest {
|
||||
instanceOf(MappingJackson2HttpMessageConverter.class), instanceOf(MappingJacksonHttpMessageConverter.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #134
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void halSetupIsAppliedToAllTransitiveComponentsInRequestMappingHandlerAdapter() {
|
||||
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(HalConfig.class);
|
||||
|
||||
Jackson2ModuleRegisteringBeanPostProcessor postProcessor = new HypermediaSupportBeanDefinitionRegistrar.Jackson2ModuleRegisteringBeanPostProcessor();
|
||||
postProcessor.setBeanFactory(context);
|
||||
|
||||
RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);
|
||||
|
||||
assertThat(adapter.getMessageConverters().get(0).getSupportedMediaTypes(), hasItem(MediaTypes.HAL_JSON));
|
||||
|
||||
boolean found = false;
|
||||
|
||||
for (HandlerMethodArgumentResolver resolver : adapter.getArgumentResolvers().getResolvers()) {
|
||||
|
||||
if (resolver instanceof AbstractMessageConverterMethodArgumentResolver) {
|
||||
|
||||
found = true;
|
||||
|
||||
AbstractMessageConverterMethodArgumentResolver processor = (AbstractMessageConverterMethodArgumentResolver) resolver;
|
||||
List<HttpMessageConverter<?>> converters = (List<HttpMessageConverter<?>>) ReflectionTestUtils.getField(
|
||||
processor, "messageConverters");
|
||||
|
||||
assertThat(converters.get(0).getSupportedMediaTypes(), hasItem(MediaTypes.HAL_JSON));
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(found, is(true));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(DelegateConfig.class)
|
||||
static class HalConfig {
|
||||
|
||||
Reference in New Issue
Block a user