From 6ae89ea397c2fa7796651b355a976c4db2f85f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Tue, 13 May 2025 14:38:47 +0200 Subject: [PATCH] Introduce Jackson 3 support to MessageBrokerBeanDefinitionParser See gh-33798 --- .../MessageBrokerBeanDefinitionParser.java | 17 +++++++++++++++-- .../MessageBrokerBeanDefinitionParserTests.java | 8 ++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java index cf6f1753c90..109f9791e52 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ import org.springframework.messaging.converter.ByteArrayMessageConverter; import org.springframework.messaging.converter.CompositeMessageConverter; import org.springframework.messaging.converter.DefaultContentTypeResolver; import org.springframework.messaging.converter.GsonMessageConverter; +import org.springframework.messaging.converter.JacksonJsonMessageConverter; import org.springframework.messaging.converter.JsonbMessageConverter; import org.springframework.messaging.converter.MappingJackson2MessageConverter; import org.springframework.messaging.converter.StringMessageConverter; @@ -98,6 +99,7 @@ import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler; * * @author Brian Clozel * @author Rossen Stoyanchev + * @author Sebastien Deleuze * @since 4.0 */ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { @@ -114,6 +116,8 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { private static final int DEFAULT_MAPPING_ORDER = 1; + private static final boolean jacksonPresent; + private static final boolean jackson2Present; private static final boolean gsonPresent; @@ -124,6 +128,7 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { static { ClassLoader classLoader = MessageBrokerBeanDefinitionParser.class.getClassLoader(); + jacksonPresent = ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", classLoader); jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader); @@ -488,6 +493,7 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { return new RuntimeBeanReference(beanName); } + @SuppressWarnings("removal") private RuntimeBeanReference registerMessageConverter( Element element, ParserContext context, @Nullable Object source) { @@ -504,7 +510,14 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { converters.setSource(source); converters.add(new RootBeanDefinition(StringMessageConverter.class)); converters.add(new RootBeanDefinition(ByteArrayMessageConverter.class)); - if (jackson2Present) { + if (jacksonPresent) { + RootBeanDefinition jacksonConverterDef = new RootBeanDefinition(JacksonJsonMessageConverter.class); + RootBeanDefinition resolverDef = new RootBeanDefinition(DefaultContentTypeResolver.class); + resolverDef.getPropertyValues().add("defaultMimeType", MimeTypeUtils.APPLICATION_JSON); + jacksonConverterDef.getPropertyValues().add("contentTypeResolver", resolverDef); + converters.add(jacksonConverterDef); + } + else if (jackson2Present) { RootBeanDefinition jacksonConverterDef = new RootBeanDefinition(MappingJackson2MessageConverter.class); RootBeanDefinition resolverDef = new RootBeanDefinition(DefaultContentTypeResolver.class); resolverDef.getPropertyValues().add("defaultMimeType", MimeTypeUtils.APPLICATION_JSON); diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java index ca66aabd759..cbcad8b5e8c 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ import org.springframework.messaging.converter.ByteArrayMessageConverter; import org.springframework.messaging.converter.CompositeMessageConverter; import org.springframework.messaging.converter.ContentTypeResolver; import org.springframework.messaging.converter.DefaultContentTypeResolver; -import org.springframework.messaging.converter.MappingJackson2MessageConverter; +import org.springframework.messaging.converter.JacksonJsonMessageConverter; import org.springframework.messaging.converter.MessageConverter; import org.springframework.messaging.converter.StringMessageConverter; import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; @@ -343,9 +343,9 @@ class MessageBrokerBeanDefinitionParserTests { assertThat(converters).hasSize(3); assertThat(converters).element(0).isInstanceOf(StringMessageConverter.class); assertThat(converters).element(1).isInstanceOf(ByteArrayMessageConverter.class); - assertThat(converters).element(2).isInstanceOf(MappingJackson2MessageConverter.class); + assertThat(converters).element(2).isInstanceOf(JacksonJsonMessageConverter.class); - ContentTypeResolver resolver = ((MappingJackson2MessageConverter) converters.get(2)).getContentTypeResolver(); + ContentTypeResolver resolver = ((JacksonJsonMessageConverter) converters.get(2)).getContentTypeResolver(); assertThat(((DefaultContentTypeResolver) resolver).getDefaultMimeType()).isEqualTo(MimeTypeUtils.APPLICATION_JSON); DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(annotationMethodMessageHandler);