Skip to content

Commit e57efda

Browse files
committed
DATACMNS-1152 - Setup of ProjectingJackson2HttpMessageConverter now tries to use unique ObjectMapper from ApplicationContext.
We're now trying to look up a uniquely available ObjectMapper instance from the application context falling back to a simple new instance in case none can be found.
1 parent 3dd3568 commit e57efda

File tree

2 files changed

+77
-9
lines changed

2 files changed

+77
-9
lines changed

src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.List;
1919

20+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2021
import org.springframework.beans.factory.ObjectFactory;
2122
import org.springframework.beans.factory.annotation.Autowired;
2223
import org.springframework.beans.factory.annotation.Qualifier;
@@ -122,7 +123,10 @@ public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
122123
if (ClassUtils.isPresent("com.jayway.jsonpath.DocumentContext", context.getClassLoader())
123124
&& ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", context.getClassLoader())) {
124125

125-
ProjectingJackson2HttpMessageConverter converter = new ProjectingJackson2HttpMessageConverter(new ObjectMapper());
126+
ObjectMapper mapper = getUniqueBean(ObjectMapper.class, context);
127+
mapper = mapper == null ? new ObjectMapper() : mapper;
128+
129+
ProjectingJackson2HttpMessageConverter converter = new ProjectingJackson2HttpMessageConverter(mapper);
126130
converter.setBeanClassLoader(context.getClassLoader());
127131
converter.setBeanFactory(context);
128132

@@ -133,4 +137,13 @@ public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
133137
converters.add(0, new XmlBeamHttpMessageConverter());
134138
}
135139
}
140+
141+
private static <T> T getUniqueBean(Class<T> type, ApplicationContext context) {
142+
143+
try {
144+
return context.getBean(type);
145+
} catch (NoSuchBeanDefinitionException o_O) {
146+
return null;
147+
}
148+
}
136149
}

src/test/java/org/springframework/data/web/config/SpringDataWebConfigurationIntegrationTests.java

+63-8
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@
1919
import static org.junit.Assert.*;
2020

2121
import java.util.ArrayList;
22+
import java.util.Arrays;
2223
import java.util.List;
24+
import java.util.function.Consumer;
2325

2426
import org.hamcrest.Matcher;
2527
import org.junit.Test;
2628
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
29+
import org.springframework.context.annotation.Bean;
30+
import org.springframework.context.annotation.Configuration;
2731
import org.springframework.data.classloadersupport.HidingClassLoader;
2832
import org.springframework.data.web.ProjectingJackson2HttpMessageConverter;
2933
import org.springframework.data.web.XmlBeamHttpMessageConverter;
3034
import org.springframework.http.converter.HttpMessageConverter;
35+
import org.springframework.test.util.ReflectionTestUtils;
3136
import org.xmlbeam.XBProjector;
3237

3338
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -47,7 +52,7 @@ public void shouldNotLoadJacksonConverterWhenJacksonNotPresent() {
4752

4853
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
4954

50-
createConfigWithClassLoader(HidingClassLoader.hide(ObjectMapper.class)).extendMessageConverters(converters);
55+
createConfigWithClassLoader(HidingClassLoader.hide(ObjectMapper.class), triggerExtendConverters(converters));
5156

5257
assertThat(converters, not(hasItem(instanceWithClassName(ProjectingJackson2HttpMessageConverter.class))));
5358
}
@@ -57,7 +62,7 @@ public void shouldNotLoadJacksonConverterWhenJaywayNotPresent() {
5762

5863
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
5964

60-
createConfigWithClassLoader(HidingClassLoader.hide(DocumentContext.class)).extendMessageConverters(converters);
65+
createConfigWithClassLoader(HidingClassLoader.hide(DocumentContext.class), triggerExtendConverters(converters));
6166

6267
assertThat(converters, not(hasItem(instanceWithClassName(ProjectingJackson2HttpMessageConverter.class))));
6368
}
@@ -67,8 +72,7 @@ public void shouldNotLoadXBeamConverterWhenXBeamNotPresent() throws Exception {
6772

6873
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
6974

70-
ClassLoader classLoader = HidingClassLoader.hide(XBProjector.class);
71-
createConfigWithClassLoader(classLoader).extendMessageConverters(converters);
75+
createConfigWithClassLoader(HidingClassLoader.hide(XBProjector.class), triggerExtendConverters(converters));
7276

7377
assertThat(converters, not(hasItem(instanceWithClassName(XmlBeamHttpMessageConverter.class))));
7478
}
@@ -78,21 +82,49 @@ public void shouldLoadAllConvertersWhenDependenciesArePresent() throws Exception
7882

7983
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
8084

81-
createConfigWithClassLoader(getClass().getClassLoader()).extendMessageConverters(converters);
85+
createConfigWithClassLoader(getClass().getClassLoader(), triggerExtendConverters(converters));
8286

8387
assertThat(converters, hasItem(instanceWithClassName(XmlBeamHttpMessageConverter.class)));
8488
assertThat(converters, hasItem(instanceWithClassName(ProjectingJackson2HttpMessageConverter.class)));
8589
}
8690

87-
private SpringDataWebConfiguration createConfigWithClassLoader(ClassLoader classLoader) {
91+
@Test // DATACMNS-1152
92+
public void usesCustomObjectMapper() {
93+
94+
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
95+
96+
createConfigWithClassLoader(getClass().getClassLoader(), triggerExtendConverters(converters),
97+
SomeConfiguration.class);
98+
99+
boolean found = false;
100+
101+
for (HttpMessageConverter<?> converter : converters) {
102+
103+
if (converter instanceof ProjectingJackson2HttpMessageConverter) {
104+
105+
found = true;
106+
107+
assertThat(ReflectionTestUtils.getField(converter, "objectMapper"),
108+
is(sameInstance((Object) SomeConfiguration.MAPPER)));
109+
}
110+
}
111+
112+
assertThat(found, is(true));
113+
}
114+
115+
private void createConfigWithClassLoader(ClassLoader classLoader, Consumer<SpringDataWebConfiguration> callback,
116+
Class<?>... additionalConfigurationClasses) {
117+
118+
List<Class<?>> configClasses = new ArrayList<Class<?>>(Arrays.asList(additionalConfigurationClasses));
119+
configClasses.add(SpringDataWebConfiguration.class);
88120

89121
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
90-
SpringDataWebConfiguration.class);
122+
configClasses.toArray(new Class<?>[configClasses.size()]));
91123

92124
context.setClassLoader(classLoader);
93125

94126
try {
95-
return context.getBean(SpringDataWebConfiguration.class);
127+
callback.accept(context.getBean(SpringDataWebConfiguration.class));
96128
} finally {
97129
context.close();
98130
}
@@ -108,4 +140,27 @@ private SpringDataWebConfiguration createConfigWithClassLoader(ClassLoader class
108140
private static <T> Matcher<? super T> instanceWithClassName(Class<T> expectedClass) {
109141
return hasProperty("class", hasProperty("name", equalTo(expectedClass.getName())));
110142
}
143+
144+
private static Consumer<SpringDataWebConfiguration> triggerExtendConverters(
145+
final List<HttpMessageConverter<?>> converters) {
146+
147+
return new Consumer<SpringDataWebConfiguration>() {
148+
149+
@Override
150+
public void accept(SpringDataWebConfiguration t) {
151+
t.extendMessageConverters(converters);
152+
}
153+
};
154+
}
155+
156+
@Configuration
157+
static class SomeConfiguration {
158+
159+
static ObjectMapper MAPPER = new ObjectMapper();
160+
161+
@Bean
162+
ObjectMapper mapper() {
163+
return MAPPER;
164+
}
165+
}
111166
}

0 commit comments

Comments
 (0)