Skip to content

Commit b682cda

Browse files
committed
GH-3151: Refine Jackson 3-based classes to accept only JsonMapper
Fixes: #3151 To avoid the problem when any other possible `ObjectMapper` extension ((`XmlMapper`, `SmileMapper`, `CBORMapper`) could be injected into just JSON-based components, it is better to concentrate only on specific implementation. * Fix `JacksonJsonMessageConverter` and `JacksonProjectingMessageConverter` to accept only `JsonMapper` * Fix `JacksonXmlMessageConverter` to disable `setUseProjectionForInterfaces()` since projection in Spring Data is implemented only for JSON views
1 parent 8d5a5d7 commit b682cda

File tree

5 files changed

+29
-25
lines changed

5 files changed

+29
-25
lines changed

spring-amqp/src/main/java/org/springframework/amqp/support/converter/AbstractJacksonMessageConverter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import tools.jackson.core.JacksonException;
3030
import tools.jackson.databind.JavaType;
3131
import tools.jackson.databind.ObjectMapper;
32+
import tools.jackson.databind.json.JsonMapper;
3233

3334
import org.springframework.amqp.core.Message;
3435
import org.springframework.amqp.core.MessageProperties;
@@ -268,7 +269,7 @@ public void setUseProjectionForInterfaces(boolean useProjectionForInterfaces) {
268269
if (!ClassUtils.isPresent("org.springframework.data.projection.ProjectionFactory", this.classLoader)) {
269270
throw new IllegalStateException("'spring-data-commons' is required to use Projection Interfaces");
270271
}
271-
this.projectingConverter = new JacksonProjectingMessageConverter(this.objectMapper);
272+
this.projectingConverter = new JacksonProjectingMessageConverter((JsonMapper) this.objectMapper);
272273
}
273274
}
274275

spring-amqp/src/main/java/org/springframework/amqp/support/converter/JacksonJsonMessageConverter.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import tools.jackson.databind.DeserializationFeature;
2020
import tools.jackson.databind.MapperFeature;
21-
import tools.jackson.databind.ObjectMapper;
2221
import tools.jackson.databind.json.JsonMapper;
2322

2423
import org.springframework.amqp.core.MessageProperties;
@@ -34,16 +33,16 @@
3433
public class JacksonJsonMessageConverter extends AbstractJacksonMessageConverter {
3534

3635
/**
37-
* Construct with an internal {@link ObjectMapper} instance and trusted packed to all ({@code *}).
36+
* Construct with an internal {@link JsonMapper} instance and trusted packed to all ({@code *}).
3837
*/
3938
public JacksonJsonMessageConverter() {
4039
this("*");
4140
}
4241

4342
/**
44-
* Construct with an internal {@link ObjectMapper} instance.
43+
* Construct with an internal {@link JsonMapper} instance.
4544
* The {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES}
46-
* and {@link MapperFeature#DEFAULT_VIEW_INCLUSION} are set to false on the {@link ObjectMapper}.
45+
* and {@link MapperFeature#DEFAULT_VIEW_INCLUSION} are set to false on the {@link JsonMapper}.
4746
* @param trustedPackages the trusted Java packages for deserialization
4847
* @see DefaultJacksonJavaTypeMapper#setTrustedPackages(String...)
4948
*/
@@ -57,21 +56,21 @@ public JacksonJsonMessageConverter(String... trustedPackages) {
5756
}
5857

5958
/**
60-
* Construct with the provided {@link ObjectMapper} instance and trusted packed to all ({@code *}).
61-
* @param jsonObjectMapper the {@link ObjectMapper} to use.
59+
* Construct with the provided {@link JsonMapper} instance and trusted packed to all ({@code *}).
60+
* @param jsonMapper the {@link JsonMapper} to use.
6261
*/
63-
public JacksonJsonMessageConverter(ObjectMapper jsonObjectMapper) {
64-
this(jsonObjectMapper, "*");
62+
public JacksonJsonMessageConverter(JsonMapper jsonMapper) {
63+
this(jsonMapper, "*");
6564
}
6665

6766
/**
68-
* Construct with the provided {@link ObjectMapper} instance.
69-
* @param jsonObjectMapper the {@link ObjectMapper} to use.
67+
* Construct with the provided {@link JsonMapper} instance.
68+
* @param jsonMapper the {@link JsonMapper} to use.
7069
* @param trustedPackages the trusted Java packages for deserialization
7170
* @see DefaultJacksonJavaTypeMapper#setTrustedPackages(String...)
7271
*/
73-
public JacksonJsonMessageConverter(ObjectMapper jsonObjectMapper, String... trustedPackages) {
74-
super(jsonObjectMapper, MimeTypeUtils.parseMimeType(MessageProperties.CONTENT_TYPE_JSON), trustedPackages);
72+
public JacksonJsonMessageConverter(JsonMapper jsonMapper, String... trustedPackages) {
73+
super(jsonMapper, MimeTypeUtils.parseMimeType(MessageProperties.CONTENT_TYPE_JSON), trustedPackages);
7574
}
7675

7776
}

spring-amqp/src/main/java/org/springframework/amqp/support/converter/JacksonProjectingMessageConverter.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import com.jayway.jsonpath.spi.mapper.MappingProvider;
2626
import org.jspecify.annotations.Nullable;
2727
import tools.jackson.databind.JavaType;
28-
import tools.jackson.databind.ObjectMapper;
28+
import tools.jackson.databind.json.JsonMapper;
2929

3030
import org.springframework.amqp.core.Message;
3131
import org.springframework.core.ResolvableType;
@@ -49,7 +49,7 @@ public class JacksonProjectingMessageConverter {
4949

5050
private final ProjectionFactory projectionFactory;
5151

52-
public JacksonProjectingMessageConverter(ObjectMapper mapper) {
52+
public JacksonProjectingMessageConverter(JsonMapper mapper) {
5353
Assert.notNull(mapper, "'mapper' cannot be null");
5454
MappingProvider provider = new Jackson3MappingProvider(mapper);
5555
MethodInterceptorFactory interceptorFactory = new JsonProjectingMethodInterceptorFactory(provider);
@@ -68,17 +68,17 @@ public Object convert(Message message, Type type) {
6868
/**
6969
* A {@link MappingProvider} implementation for Jackson 3.
7070
* Until respective implementation is there in json-path library.
71-
* @param objectMapper Jackson 3 {@link ObjectMapper}
71+
* @param jsonMapper Jackson 3 {@link JsonMapper}
7272
*/
73-
private record Jackson3MappingProvider(ObjectMapper objectMapper) implements MappingProvider {
73+
private record Jackson3MappingProvider(JsonMapper jsonMapper) implements MappingProvider {
7474

7575
@Override
7676
public <T> @Nullable T map(@Nullable Object source, Class<T> targetType, Configuration configuration) {
7777
if (source == null) {
7878
return null;
7979
}
8080
try {
81-
return this.objectMapper.convertValue(source, targetType);
81+
return this.jsonMapper.convertValue(source, targetType);
8282
}
8383
catch (Exception ex) {
8484
throw new MappingException(ex);
@@ -90,10 +90,10 @@ private record Jackson3MappingProvider(ObjectMapper objectMapper) implements Map
9090
if (source == null) {
9191
return null;
9292
}
93-
JavaType type = this.objectMapper.constructType(targetType.getType());
93+
JavaType type = this.jsonMapper.constructType(targetType.getType());
9494

9595
try {
96-
return this.objectMapper.convertValue(source, type);
96+
return this.jsonMapper.convertValue(source, type);
9797
}
9898
catch (Exception ex) {
9999
throw new MappingException(ex);

spring-amqp/src/main/java/org/springframework/amqp/support/converter/JacksonXmlMessageConverter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,9 @@ public JacksonXmlMessageConverter(XmlMapper xmlMapper, String... trustedPackages
7272
super(xmlMapper, MimeTypeUtils.parseMimeType(MessageProperties.CONTENT_TYPE_XML), trustedPackages);
7373
}
7474

75+
@Override
76+
public void setUseProjectionForInterfaces(boolean useProjectionForInterfaces) {
77+
throw new UnsupportedOperationException("This converter does not support useProjectionForInterfaces");
78+
}
79+
7580
}

spring-amqp/src/test/java/org/springframework/amqp/support/converter/JacksonJsonMessageConverterTests.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import tools.jackson.core.JacksonException;
2828
import tools.jackson.core.JsonParser;
2929
import tools.jackson.databind.DeserializationContext;
30-
import tools.jackson.databind.ObjectMapper;
3130
import tools.jackson.databind.deser.std.StdDeserializer;
3231
import tools.jackson.databind.json.JsonMapper;
3332
import tools.jackson.databind.module.SimpleModule;
@@ -89,7 +88,7 @@ public void simpleTrade() {
8988

9089
@Test
9190
public void simpleTradeOverrideMapper() {
92-
ObjectMapper mapper =
91+
JsonMapper mapper =
9392
JsonMapper.builder()
9493
.serializerFactory(BeanSerializerFactory.instance)
9594
.build();
@@ -321,7 +320,7 @@ void customAbstractClass() {
321320
messageProperties.setHeader("__TypeId__", String.class.getName());
322321
messageProperties.setInferredArgumentType(Baz.class);
323322
Message message = new Message(bytes, messageProperties);
324-
ObjectMapper mapper = JsonMapper.builder().addModule(new BazModule()).build();
323+
JsonMapper mapper = JsonMapper.builder().addModule(new BazModule()).build();
325324
JacksonJsonMessageConverter messageConverter = new JacksonJsonMessageConverter(mapper);
326325
messageConverter.setAlwaysConvertToInferredType(true);
327326
Baz baz = (Baz) messageConverter.fromMessage(message);
@@ -347,7 +346,7 @@ void customAbstractClassList() throws Exception {
347346
messageProperties.setHeader("__TypeId__", String.class.getName());
348347
messageProperties.setInferredArgumentType(getClass().getDeclaredMethod("bazLister").getGenericReturnType());
349348
Message message = new Message(bytes, messageProperties);
350-
ObjectMapper mapper = JsonMapper.builder().addModule(new BazModule()).build();
349+
JsonMapper mapper = JsonMapper.builder().addModule(new BazModule()).build();
351350
JacksonJsonMessageConverter jsonMessageConverter = new JacksonJsonMessageConverter(mapper);
352351
jsonMessageConverter.setAlwaysConvertToInferredType(true);
353352
@SuppressWarnings("unchecked")
@@ -364,7 +363,7 @@ void cantDeserializeFizListUseHeaders() throws Exception {
364363
messageProperties.setHeader("__TypeId__", List.class.getName());
365364
messageProperties.setHeader("__ContentTypeId__", Buz.class.getName());
366365
Message message = new Message(bytes, messageProperties);
367-
ObjectMapper mapper = JsonMapper.builder().addModule(new BazModule()).build();
366+
JsonMapper mapper = JsonMapper.builder().addModule(new BazModule()).build();
368367
JacksonJsonMessageConverter jsonMessageConverter = new JacksonJsonMessageConverter(mapper);
369368
@SuppressWarnings("unchecked")
370369
List<Fiz> buzs = (List<Fiz>) jsonMessageConverter.fromMessage(message);

0 commit comments

Comments
 (0)