Skip to content

Commit 7acd4ae

Browse files
committed
Introduce Jackson 3 support to AnnotationDrivenBeanDefinitionParser
See gh-33798
1 parent 0ad4fca commit 7acd4ae

File tree

2 files changed

+54
-16
lines changed

2 files changed

+54
-16
lines changed

spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/XmlConfigTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void person() throws Exception {
7373
this.mockMvc.perform(get("/person/5").accept(MediaType.APPLICATION_JSON))
7474
.andDo(print())
7575
.andExpect(status().isOk())
76-
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}"));
76+
.andExpect(content().string("{\"name\":\"Joe\",\"someBoolean\":false,\"someDouble\":0.0}"));
7777
}
7878

7979
}

spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -47,16 +47,21 @@
4747
import org.springframework.http.converter.ResourceHttpMessageConverter;
4848
import org.springframework.http.converter.ResourceRegionHttpMessageConverter;
4949
import org.springframework.http.converter.StringHttpMessageConverter;
50+
import org.springframework.http.converter.cbor.JacksonCborHttpMessageConverter;
5051
import org.springframework.http.converter.cbor.MappingJackson2CborHttpMessageConverter;
5152
import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
5253
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
5354
import org.springframework.http.converter.json.GsonHttpMessageConverter;
5455
import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
56+
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
5557
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
58+
import org.springframework.http.converter.smile.JacksonSmileHttpMessageConverter;
5659
import org.springframework.http.converter.smile.MappingJackson2SmileHttpMessageConverter;
5760
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
61+
import org.springframework.http.converter.xml.JacksonXmlHttpMessageConverter;
5862
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
5963
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
64+
import org.springframework.http.converter.yaml.JacksonYamlHttpMessageConverter;
6065
import org.springframework.http.converter.yaml.MappingJackson2YamlHttpMessageConverter;
6166
import org.springframework.util.Assert;
6267
import org.springframework.util.ClassUtils;
@@ -151,6 +156,7 @@
151156
* @author Brian Clozel
152157
* @author Agim Emruli
153158
* @author Hyoungjune Kim
159+
* @author Sebastien Deleuze
154160
* @since 3.0
155161
*/
156162
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
@@ -168,14 +174,24 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
168174

169175
private static final boolean jaxb2Present;
170176

177+
private static final boolean jacksonPresent;
178+
171179
private static final boolean jackson2Present;
172180

181+
private static final boolean jacksonXmlPresent;
182+
173183
private static final boolean jackson2XmlPresent;
174184

185+
private static final boolean jacksonSmilePresent;
186+
175187
private static final boolean jackson2SmilePresent;
176188

189+
private static final boolean jacksonCborPresent;
190+
177191
private static final boolean jackson2CborPresent;
178192

193+
private static final boolean jacksonYamlPresent;
194+
179195
private static final boolean jackson2YamlPresent;
180196

181197
private static final boolean gsonPresent;
@@ -185,12 +201,17 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
185201
javaxValidationPresent = ClassUtils.isPresent("jakarta.validation.Validator", classLoader);
186202
romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader);
187203
jaxb2Present = ClassUtils.isPresent("jakarta.xml.bind.Binder", classLoader);
204+
jacksonPresent = ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", classLoader);
188205
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
189206
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
190-
jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
191-
jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
192-
jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);
193-
jackson2YamlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.yaml.YAMLFactory", classLoader);
207+
jacksonXmlPresent = jacksonPresent && ClassUtils.isPresent("tools.jackson.dataformat.xml.XmlMapper", classLoader);
208+
jackson2XmlPresent = jackson2Present && ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
209+
jacksonSmilePresent = jacksonPresent && ClassUtils.isPresent("tools.jackson.dataformat.smile.SmileMapper", classLoader);
210+
jackson2SmilePresent = jackson2Present && ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
211+
jacksonCborPresent = jacksonPresent && ClassUtils.isPresent("tools.jackson.dataformat.cbor.CBORMapper", classLoader);
212+
jackson2CborPresent = jackson2Present && ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader);
213+
jacksonYamlPresent = jacksonPresent && ClassUtils.isPresent("tools.jackson.dataformat.yaml.YAMLMapper", classLoader);
214+
jackson2YamlPresent = jackson2Present && ClassUtils.isPresent("com.fasterxml.jackson.dataformat.yaml.YAMLFactory", classLoader);
194215
gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
195216
}
196217

@@ -446,19 +467,19 @@ private Properties getDefaultMediaTypes() {
446467
defaultMediaTypes.put("atom", MediaType.APPLICATION_ATOM_XML_VALUE);
447468
defaultMediaTypes.put("rss", MediaType.APPLICATION_RSS_XML_VALUE);
448469
}
449-
if (jaxb2Present || jackson2XmlPresent) {
470+
if (jaxb2Present || jacksonXmlPresent || jackson2XmlPresent) {
450471
defaultMediaTypes.put("xml", MediaType.APPLICATION_XML_VALUE);
451472
}
452-
if (jackson2Present || gsonPresent) {
473+
if (jacksonPresent || jackson2Present || gsonPresent) {
453474
defaultMediaTypes.put("json", MediaType.APPLICATION_JSON_VALUE);
454475
}
455-
if (jackson2SmilePresent) {
476+
if (jacksonSmilePresent || jackson2SmilePresent) {
456477
defaultMediaTypes.put("smile", "application/x-jackson-smile");
457478
}
458-
if (jackson2CborPresent) {
479+
if (jacksonCborPresent || jackson2CborPresent) {
459480
defaultMediaTypes.put("cbor", MediaType.APPLICATION_CBOR_VALUE);
460481
}
461-
if (jackson2YamlPresent) {
482+
if (jacksonYamlPresent || jackson2YamlPresent) {
462483
defaultMediaTypes.put("yaml", MediaType.APPLICATION_YAML_VALUE);
463484
}
464485
return defaultMediaTypes;
@@ -568,7 +589,10 @@ private ManagedList<?> getMessageConverters(Element element, @Nullable Object so
568589
messageConverters.add(createConverterDefinition(RssChannelHttpMessageConverter.class, source));
569590
}
570591

571-
if (jackson2XmlPresent) {
592+
if (jacksonXmlPresent) {
593+
messageConverters.add(createConverterDefinition(JacksonXmlHttpMessageConverter.class, source));
594+
}
595+
else if (jackson2XmlPresent) {
572596
Class<?> type = MappingJackson2XmlHttpMessageConverter.class;
573597
RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
574598
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
@@ -580,7 +604,10 @@ else if (jaxb2Present) {
580604
messageConverters.add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
581605
}
582606

583-
if (jackson2Present) {
607+
if (jacksonPresent) {
608+
messageConverters.add(createConverterDefinition(JacksonJsonHttpMessageConverter.class, source));
609+
}
610+
else if (jackson2Present) {
584611
Class<?> type = MappingJackson2HttpMessageConverter.class;
585612
RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
586613
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
@@ -591,23 +618,34 @@ else if (gsonPresent) {
591618
messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source));
592619
}
593620

594-
if (jackson2SmilePresent) {
621+
if (jacksonSmilePresent) {
622+
messageConverters.add(createConverterDefinition(JacksonSmileHttpMessageConverter.class, source));
623+
}
624+
else if (jackson2SmilePresent) {
595625
Class<?> type = MappingJackson2SmileHttpMessageConverter.class;
596626
RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
597627
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
598628
jacksonFactoryDef.getPropertyValues().add("factory", new RootBeanDefinition(SmileFactory.class));
599629
jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
600630
messageConverters.add(jacksonConverterDef);
601631
}
602-
if (jackson2CborPresent) {
632+
633+
if (jacksonCborPresent) {
634+
messageConverters.add(createConverterDefinition(JacksonCborHttpMessageConverter.class, source));
635+
}
636+
else if (jackson2CborPresent) {
603637
Class<?> type = MappingJackson2CborHttpMessageConverter.class;
604638
RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
605639
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
606640
jacksonFactoryDef.getPropertyValues().add("factory", new RootBeanDefinition(CBORFactory.class));
607641
jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
608642
messageConverters.add(jacksonConverterDef);
609643
}
610-
if(jackson2YamlPresent) {
644+
645+
if (jacksonYamlPresent) {
646+
messageConverters.add(createConverterDefinition(JacksonYamlHttpMessageConverter.class, source));
647+
}
648+
else if (jackson2YamlPresent) {
611649
Class<?> type = MappingJackson2YamlHttpMessageConverter.class;
612650
RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
613651
GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);

0 commit comments

Comments
 (0)