From 8ec9ab66986e466cd0e27a4c6abfa2c6c81a0faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Wed, 15 Oct 2025 10:57:11 +0200 Subject: [PATCH] Add builder-based constructors to Jackson 3 infrastructure This commit also polishes documentation, constructor parameter and field names. Closes gh-35597 --- .../JacksonJsonMessageConverter.java | 45 +++++++------ .../JacksonJsonMessageConverter.java | 67 ++++++++++++------- .../http/codec/cbor/JacksonCborDecoder.java | 23 ++++++- .../http/codec/cbor/JacksonCborEncoder.java | 23 ++++++- .../http/codec/json/JacksonJsonDecoder.java | 29 ++++++-- .../http/codec/json/JacksonJsonEncoder.java | 35 +++++++--- .../http/codec/smile/JacksonSmileDecoder.java | 27 ++++++-- .../http/codec/smile/JacksonSmileEncoder.java | 31 ++++++--- .../cbor/JacksonCborHttpMessageConverter.java | 20 +++++- .../json/JacksonJsonHttpMessageConverter.java | 25 ++++--- .../JacksonSmileHttpMessageConverter.java | 20 +++++- .../xml/JacksonXmlHttpMessageConverter.java | 5 +- .../yaml/JacksonYamlHttpMessageConverter.java | 20 +++++- .../web/servlet/view/AbstractJacksonView.java | 12 ++-- .../servlet/view/json/JacksonJsonView.java | 16 ++++- .../web/servlet/view/xml/JacksonXmlView.java | 16 ++++- .../frame/JacksonJsonSockJsMessageCodec.java | 30 ++++++--- 17 files changed, 325 insertions(+), 119 deletions(-) diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/JacksonJsonMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/JacksonJsonMessageConverter.java index e1d0d9f2dfa..6f969b2cc63 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/JacksonJsonMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/JacksonJsonMessageConverter.java @@ -48,9 +48,6 @@ import org.springframework.util.ClassUtils; * {@link #setTargetType targetType} is set to {@link MessageType#TEXT}. * Converts from a {@link TextMessage} or {@link BytesMessage} to an object. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * * @author Sebastien Deleuze * @since 7.0 */ @@ -62,7 +59,7 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC public static final String DEFAULT_ENCODING = "UTF-8"; - private final JsonMapper jsonMapper; + private final JsonMapper mapper; private MessageType targetType = MessageType.BYTES; @@ -85,17 +82,27 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC * {@link MapperBuilder#findModules(ClassLoader)}. */ public JacksonJsonMessageConverter() { - this.jsonMapper = JsonMapper.builder().findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build(); + this(JsonMapper.builder()); + } + + /** + * Construct a new instance with the provided {@link JsonMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s found + * by {@link MapperBuilder#findModules(ClassLoader)}. + * @see JsonMapper#builder() + */ + public JacksonJsonMessageConverter(JsonMapper.Builder builder) { + Assert.notNull(builder, "JsonMapper.Builder must not be null"); + this.mapper = builder.findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build(); } /** * Construct a new instance with the provided {@link JsonMapper}. * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ - public JacksonJsonMessageConverter(JsonMapper jsonMapper) { - Assert.notNull(jsonMapper, "JsonMapper must not be null"); - this.jsonMapper = jsonMapper; + public JacksonJsonMessageConverter(JsonMapper mapper) { + Assert.notNull(mapper, "JsonMapper must not be null"); + this.mapper = mapper; } /** @@ -172,9 +179,9 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC Message message; try { message = switch (this.targetType) { - case TEXT -> mapToTextMessage(object, session, this.jsonMapper.writer()); - case BYTES -> mapToBytesMessage(object, session, this.jsonMapper.writer()); - default -> mapToMessage(object, session, this.jsonMapper.writer(), this.targetType); + case TEXT -> mapToTextMessage(object, session, this.mapper.writer()); + case BYTES -> mapToBytesMessage(object, session, this.mapper.writer()); + default -> mapToMessage(object, session, this.mapper.writer(), this.targetType); }; } catch (IOException ex) { @@ -205,10 +212,10 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC throws JMSException, MessageConversionException { if (jsonView != null) { - return toMessage(object, session, this.jsonMapper.writerWithView(jsonView)); + return toMessage(object, session, this.mapper.writerWithView(jsonView)); } else { - return toMessage(object, session, this.jsonMapper.writer()); + return toMessage(object, session, this.mapper.writer()); } } @@ -362,7 +369,7 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC throws JMSException, IOException { String body = message.getText(); - return this.jsonMapper.readValue(body, targetJavaType); + return this.mapper.readValue(body, targetJavaType); } /** @@ -385,7 +392,7 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC if (encoding != null) { try { String body = new String(bytes, encoding); - return this.jsonMapper.readValue(body, targetJavaType); + return this.mapper.readValue(body, targetJavaType); } catch (UnsupportedEncodingException ex) { throw new MessageConversionException("Cannot convert bytes to String", ex); @@ -393,7 +400,7 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC } else { // Jackson internally performs encoding detection, falling back to UTF-8. - return this.jsonMapper.readValue(bytes, targetJavaType); + return this.mapper.readValue(bytes, targetJavaType); } } @@ -436,11 +443,11 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC } Class mappedClass = this.idClassMappings.get(typeId); if (mappedClass != null) { - return this.jsonMapper.constructType(mappedClass); + return this.mapper.constructType(mappedClass); } try { Class typeClass = ClassUtils.forName(typeId, this.beanClassLoader); - return this.jsonMapper.constructType(typeClass); + return this.mapper.constructType(typeClass); } catch (Throwable ex) { throw new MessageConversionException("Failed to resolve type id [" + typeId + "]", ex); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/JacksonJsonMessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/JacksonJsonMessageConverter.java index a2eb535e6d9..a46b6e9f189 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/JacksonJsonMessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/JacksonJsonMessageConverter.java @@ -40,9 +40,6 @@ import org.springframework.util.MimeType; /** * A Jackson 3.x based {@link MessageConverter} implementation. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * * @author Sebastien Deleuze * @since 7.0 */ @@ -51,7 +48,7 @@ public class JacksonJsonMessageConverter extends AbstractMessageConverter { private static final MimeType[] DEFAULT_MIME_TYPES = new MimeType[] { new MimeType("application", "json"), new MimeType("application", "*+json")}; - private final JsonMapper jsonMapper; + private final JsonMapper mapper; /** @@ -71,36 +68,58 @@ public class JacksonJsonMessageConverter extends AbstractMessageConverter { * @param supportedMimeTypes the supported MIME types */ public JacksonJsonMessageConverter(MimeType... supportedMimeTypes) { - super(supportedMimeTypes); - this.jsonMapper = JsonMapper.builder().findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build(); + this(JsonMapper.builder(), supportedMimeTypes); } /** * Construct a new instance with the provided {@link JsonMapper}. * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ - public JacksonJsonMessageConverter(JsonMapper jsonMapper) { - this(jsonMapper, DEFAULT_MIME_TYPES); + public JacksonJsonMessageConverter(JsonMapper mapper) { + this(mapper, DEFAULT_MIME_TYPES); + } + + + /** + * Construct a new instance with the provided {@link JsonMapper.Builder} customized + * with the {@link tools.jackson.databind.JacksonModule}s found + * by {@link MapperBuilder#findModules(ClassLoader)}. + * @see JsonMapper#builder() + */ + public JacksonJsonMessageConverter(JsonMapper.Builder builder) { + this(builder, DEFAULT_MIME_TYPES); } /** * Construct a new instance with the provided {@link JsonMapper} and the * provided {@link MimeType}s. * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ - public JacksonJsonMessageConverter(JsonMapper jsonMapper, MimeType... supportedMimeTypes) { + public JacksonJsonMessageConverter(JsonMapper mapper, MimeType... supportedMimeTypes) { super(supportedMimeTypes); - Assert.notNull(jsonMapper, "JsonMapper must not be null"); - this.jsonMapper = jsonMapper; + Assert.notNull(mapper, "JsonMapper must not be null"); + this.mapper = mapper; } + /** + * Construct a new instance with the provided {@link JsonMapper} customized + * with the {@link tools.jackson.databind.JacksonModule}s found by + * {@link MapperBuilder#findModules(ClassLoader)}, and the provided + * {@link MimeType}s. + * @see JsonMapper#builder() + */ + public JacksonJsonMessageConverter(JsonMapper.Builder builder, MimeType... supportedMimeTypes) { + super(supportedMimeTypes); + Assert.notNull(builder, "JsonMapper.Builder must not be null"); + this.mapper = builder.findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build(); + } + + /** * Return the underlying {@code JsonMapper} for this converter. */ protected JsonMapper getJsonMapper() { - return this.jsonMapper; + return this.mapper; } @Override @@ -121,7 +140,7 @@ public class JacksonJsonMessageConverter extends AbstractMessageConverter { @Override protected @Nullable Object convertFromInternal(Message message, Class targetClass, @Nullable Object conversionHint) { - JavaType javaType = this.jsonMapper.constructType(getResolvedType(targetClass, conversionHint)); + JavaType javaType = this.mapper.constructType(getResolvedType(targetClass, conversionHint)); Object payload = message.getPayload(); Class view = getSerializationView(conversionHint); try { @@ -130,19 +149,19 @@ public class JacksonJsonMessageConverter extends AbstractMessageConverter { } else if (payload instanceof byte[] bytes) { if (view != null) { - return this.jsonMapper.readerWithView(view).forType(javaType).readValue(bytes); + return this.mapper.readerWithView(view).forType(javaType).readValue(bytes); } else { - return this.jsonMapper.readValue(bytes, javaType); + return this.mapper.readValue(bytes, javaType); } } else { // Assuming a text-based source payload if (view != null) { - return this.jsonMapper.readerWithView(view).forType(javaType).readValue(payload.toString()); + return this.mapper.readerWithView(view).forType(javaType).readValue(payload.toString()); } else { - return this.jsonMapper.readValue(payload.toString(), javaType); + return this.mapper.readValue(payload.toString(), javaType); } } } @@ -160,12 +179,12 @@ public class JacksonJsonMessageConverter extends AbstractMessageConverter { if (byte[].class == getSerializedPayloadClass()) { ByteArrayOutputStream out = new ByteArrayOutputStream(1024); JsonEncoding encoding = getJsonEncoding(getMimeType(headers)); - try (JsonGenerator generator = this.jsonMapper.createGenerator(out, encoding)) { + try (JsonGenerator generator = this.mapper.createGenerator(out, encoding)) { if (view != null) { - this.jsonMapper.writerWithView(view).writeValue(generator, payload); + this.mapper.writerWithView(view).writeValue(generator, payload); } else { - this.jsonMapper.writeValue(generator, payload); + this.mapper.writeValue(generator, payload); } payload = out.toByteArray(); } @@ -174,10 +193,10 @@ public class JacksonJsonMessageConverter extends AbstractMessageConverter { // Assuming a text-based target payload Writer writer = new StringWriter(1024); if (view != null) { - this.jsonMapper.writerWithView(view).writeValue(writer, payload); + this.mapper.writerWithView(view).writeValue(writer, payload); } else { - this.jsonMapper.writeValue(writer, payload); + this.mapper.writeValue(writer, payload); } payload = writer.toString(); } diff --git a/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborDecoder.java index c6669c04857..293d3c6885b 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborDecoder.java @@ -51,17 +51,38 @@ public class JacksonCborDecoder extends AbstractJacksonDecoder { super(CBORMapper.builder(), MediaType.APPLICATION_CBOR); } + /** + * Construct a new instance with the provided {@link CBORMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}. + * @see CBORMapper#builder() + */ + public JacksonCborDecoder(CBORMapper.Builder builder) { + super(builder, MediaType.APPLICATION_CBOR); + } + /** * Construct a new instance with the provided {@link CBORMapper}. + * @see CBORMapper#builder() */ public JacksonCborDecoder(CBORMapper mapper) { super(mapper, MediaType.APPLICATION_CBOR); } + /** + * Construct a new instance with the provided {@link CBORMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}, and + * {@link MimeType}s. + * @see CBORMapper#builder() + */ + public JacksonCborDecoder(CBORMapper.Builder builder, MimeType... mimeTypes) { + super(builder, mimeTypes); + } + /** * Construct a new instance with the provided {@link CBORMapper} and {@link MimeType}s. * @see CBORMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonCborDecoder(CBORMapper mapper, MimeType... mimeTypes) { super(mapper, mimeTypes); diff --git a/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborEncoder.java index 980b1299c20..f7a6527cebd 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborEncoder.java @@ -52,19 +52,38 @@ public class JacksonCborEncoder extends AbstractJacksonEncoder { super(CBORMapper.builder(), MediaType.APPLICATION_CBOR); } + /** + * Construct a new instance with the provided {@link CBORMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}. + * @see CBORMapper#builder() + */ + public JacksonCborEncoder(CBORMapper.Builder builder) { + super(builder, MediaType.APPLICATION_CBOR); + } + /** * Construct a new instance with the provided {@link CBORMapper}. * @see CBORMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonCborEncoder(CBORMapper mapper) { super(mapper, MediaType.APPLICATION_CBOR); } + /** + * Construct a new instance with the provided {@link CBORMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}, and + * {@link MimeType}s. + * @see CBORMapper#builder() + */ + public JacksonCborEncoder(CBORMapper.Builder builder, MimeType... mimeTypes) { + super(builder, mimeTypes); + } + /** * Construct a new instance with the provided {@link CBORMapper} and {@link MimeType}s. * @see CBORMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonCborEncoder(CBORMapper mapper, MimeType... mimeTypes) { super(mapper, mimeTypes); diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonDecoder.java index 096235fab80..e0feef2f812 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonDecoder.java @@ -42,9 +42,6 @@ import org.springframework.util.MimeTypeUtils; * Jackson 3.x * leveraging non-blocking parsing. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * * @author Sebastien Deleuze * @since 7.0 * @see JacksonJsonEncoder @@ -71,19 +68,37 @@ public class JacksonJsonDecoder extends AbstractJacksonDecoder { super(JsonMapper.builder(), DEFAULT_JSON_MIME_TYPES); } + /** + * Construct a new instance with the provided {@link JsonMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}. + * @see JsonMapper#builder() + */ + public JacksonJsonDecoder(JsonMapper.Builder builder) { + super(builder, DEFAULT_JSON_MIME_TYPES); + } + /** * Construct a new instance with the provided {@link JsonMapper}. * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ public JacksonJsonDecoder(JsonMapper mapper) { - this(mapper, DEFAULT_JSON_MIME_TYPES); + super(mapper, DEFAULT_JSON_MIME_TYPES); + } + + /** + * Construct a new instance with the provided {@link JsonMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}, and + * {@link MimeType}s. + * @see JsonMapper#builder() + */ + public JacksonJsonDecoder(JsonMapper.Builder builder, MimeType... mimeTypes) { + super(builder, mimeTypes); } /** * Construct a new instance with the provided {@link JsonMapper} and {@link MimeType}s. - * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ public JacksonJsonDecoder(JsonMapper mapper, MimeType... mimeTypes) { super(mapper, mimeTypes); diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonEncoder.java index 992f712d874..74251313171 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonEncoder.java @@ -43,9 +43,6 @@ import org.springframework.util.MimeType; * use cases, {@link Flux} elements are collected into a {@link List} before * serialization for performance reason. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * * @author Sebastien Deleuze * @since 7.0 * @see JacksonJsonDecoder @@ -72,26 +69,44 @@ public class JacksonJsonEncoder extends AbstractJacksonEncoder { * {@link ProblemDetailJacksonMixin}. */ public JacksonJsonEncoder() { - super(JsonMapper.builder().addMixIn(ProblemDetail.class, ProblemDetailJacksonMixin.class), - DEFAULT_JSON_MIME_TYPES); - setStreamingMediaTypes(List.of(MediaType.APPLICATION_NDJSON)); - this.ssePrettyPrinter = initSsePrettyPrinter(); + this(JsonMapper.builder(), DEFAULT_JSON_MIME_TYPES); + } + + /** + * Construct a new instance with a {@link JsonMapper.Builder} customized + * with the {@link tools.jackson.databind.JacksonModule}s found by + * {@link MapperBuilder#findModules(ClassLoader)} and + * {@link ProblemDetailJacksonMixin}. + * @see JsonMapper#builder() + */ + public JacksonJsonEncoder(JsonMapper.Builder builder) { + this(builder, DEFAULT_JSON_MIME_TYPES); } /** * Construct a new instance with the provided {@link JsonMapper}. - * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ public JacksonJsonEncoder(JsonMapper mapper) { this(mapper, DEFAULT_JSON_MIME_TYPES); } + /** + * Construct a new instance with the provided {@link JsonMapper.Builder} customized + * with the {@link tools.jackson.databind.JacksonModule}s found by + * {@link MapperBuilder#findModules(ClassLoader)} and + * {@link ProblemDetailJacksonMixin}, and {@link MimeType}s. + * @see JsonMapper#builder() + */ + public JacksonJsonEncoder(JsonMapper.Builder builder, MimeType... mimeTypes) { + super(builder.addMixIn(ProblemDetail.class, ProblemDetailJacksonMixin.class), mimeTypes); + setStreamingMediaTypes(List.of(MediaType.APPLICATION_NDJSON)); + this.ssePrettyPrinter = initSsePrettyPrinter(); + } + /** * Construct a new instance with the provided {@link JsonMapper} and * {@link MimeType}s. * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ public JacksonJsonEncoder(JsonMapper mapper, MimeType... mimeTypes) { super(mapper, mimeTypes); diff --git a/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileDecoder.java index 26b87361460..5bbaaac7ee8 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileDecoder.java @@ -26,9 +26,6 @@ import org.springframework.util.MimeType; * Decode a byte stream into Smile and convert to Objects with Jackson 3.x, * leveraging non-blocking parsing. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * * @author Sebastien Deleuze * @since 7.0 * @see JacksonSmileEncoder @@ -44,24 +41,44 @@ public class JacksonSmileDecoder extends AbstractJacksonDecoder { * Construct a new instance with a {@link SmileMapper} customized with the * {@link tools.jackson.databind.JacksonModule}s found by * {@link MapperBuilder#findModules(ClassLoader)}. + * @see SmileMapper#builder() */ public JacksonSmileDecoder() { super(SmileMapper.builder(), DEFAULT_SMILE_MIME_TYPES); } + /** + * Construct a new instance with the provided {@link SmileMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}. + * @see SmileMapper#builder() + */ + public JacksonSmileDecoder(SmileMapper.Builder builder) { + this(builder, DEFAULT_SMILE_MIME_TYPES); + } + /** * Construct a new instance with the provided {@link SmileMapper}. * @see SmileMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonSmileDecoder(SmileMapper mapper) { this(mapper, DEFAULT_SMILE_MIME_TYPES); } + /** + * Construct a new instance with the provided {@link SmileMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}, and + * {@link MimeType}s. + * @see SmileMapper#builder() + */ + public JacksonSmileDecoder(SmileMapper.Builder builder, MimeType... mimeTypes) { + super(builder, mimeTypes); + } + /** * Construct a new instance with the provided {@link SmileMapper} and {@link MimeType}s. * @see SmileMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonSmileDecoder(SmileMapper mapper, MimeType... mimeTypes) { super(mapper, mimeTypes); diff --git a/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileEncoder.java index 32eef1291d2..22755a8624e 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/smile/JacksonSmileEncoder.java @@ -34,9 +34,6 @@ import org.springframework.util.MimeType; *

For non-streaming use cases, {@link Flux} elements are collected into a {@link List} * before serialization for performance reasons. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * * @author Sebastien Deleuze * @since 7.0 * @see JacksonSmileDecoder @@ -59,24 +56,42 @@ public class JacksonSmileEncoder extends AbstractJacksonEncoder { * {@link MapperBuilder#findModules(ClassLoader)}. */ public JacksonSmileEncoder() { - super(SmileMapper.builder(), DEFAULT_SMILE_MIME_TYPES); - setStreamingMediaTypes(Collections.singletonList(DEFAULT_SMILE_STREAMING_MEDIA_TYPE)); + this(SmileMapper.builder(), DEFAULT_SMILE_MIME_TYPES); + } + + /** + * Construct a new instance with the provided {@link SmileMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}. + * @see SmileMapper#builder() + */ + public JacksonSmileEncoder(SmileMapper.Builder builder) { + this(builder, DEFAULT_SMILE_MIME_TYPES); } /** * Construct a new instance with the provided {@link SmileMapper}. * @see SmileMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonSmileEncoder(SmileMapper mapper) { - super(mapper, DEFAULT_SMILE_MIME_TYPES); + this(mapper, DEFAULT_SMILE_MIME_TYPES); + } + + /** + * Construct a new instance with the provided {@link SmileMapper} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}, and + * {@link MimeType}s. + * @see SmileMapper#builder() + */ + public JacksonSmileEncoder(SmileMapper.Builder builder, MimeType... mimeTypes) { + super(builder, mimeTypes); setStreamingMediaTypes(Collections.singletonList(DEFAULT_SMILE_STREAMING_MEDIA_TYPE)); } /** * Construct a new instance with the provided {@link SmileMapper} and {@link MimeType}s. * @see SmileMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonSmileEncoder(SmileMapper mapper, MimeType... mimeTypes) { super(mapper, mimeTypes); diff --git a/spring-web/src/main/java/org/springframework/http/converter/cbor/JacksonCborHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/cbor/JacksonCborHttpMessageConverter.java index cd5fcefea94..7c56d2db428 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/cbor/JacksonCborHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/cbor/JacksonCborHttpMessageConverter.java @@ -32,8 +32,13 @@ import org.springframework.http.converter.AbstractJacksonHttpMessageConverter; * media type. This can be overridden by setting the {@link #setSupportedMediaTypes * supportedMediaTypes} property. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. + *

The following hints entries are supported: + *

* * @author Sebastien Deleuze * @since 7.0 @@ -49,10 +54,19 @@ public class JacksonCborHttpMessageConverter extends AbstractJacksonHttpMessageC super(CBORMapper.builder(), MediaType.APPLICATION_CBOR); } + /** + * Construct a new instance with the provided {@link CBORMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s + * found by {@link MapperBuilder#findModules(ClassLoader)}. + * @see CBORMapper#builder() + */ + public JacksonCborHttpMessageConverter(CBORMapper.Builder builder) { + super(builder, MediaType.APPLICATION_CBOR); + } + /** * Construct a new instance with the provided {@link CBORMapper}. * @see CBORMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonCborHttpMessageConverter(CBORMapper mapper) { super(mapper, MediaType.APPLICATION_CBOR); diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/JacksonJsonHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/JacksonJsonHttpMessageConverter.java index 5862aa6e073..e2cbed9a2da 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/JacksonJsonHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/JacksonJsonHttpMessageConverter.java @@ -41,14 +41,11 @@ import org.springframework.http.converter.AbstractJacksonHttpMessageConverter; * can be overridden by setting the {@link #setSupportedMediaTypes supportedMediaTypes} * property. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * *

The following hints entries are supported: *

* @@ -74,16 +71,26 @@ public class JacksonJsonHttpMessageConverter extends AbstractJacksonHttpMessageC * {@link ProblemDetailJacksonMixin}. */ public JacksonJsonHttpMessageConverter() { - super(JsonMapper.builder().addMixIn(ProblemDetail.class, ProblemDetailJacksonMixin.class), DEFAULT_JSON_MIME_TYPES); + this(JsonMapper.builder()); + } + + /** + * Construct a new instance with the provided {@link JsonMapper.Builder} + * customized with the {@link tools.jackson.databind.JacksonModule}s found + * by {@link MapperBuilder#findModules(ClassLoader)} and + * {@link ProblemDetailJacksonMixin}. + * @see JsonMapper#builder() + */ + public JacksonJsonHttpMessageConverter(JsonMapper.Builder builder) { + super(builder.addMixIn(ProblemDetail.class, ProblemDetailJacksonMixin.class), DEFAULT_JSON_MIME_TYPES); } /** * Construct a new instance with the provided {@link JsonMapper}. * @see JsonMapper#builder() - * @see MapperBuilder#findModules(ClassLoader) */ - public JacksonJsonHttpMessageConverter(JsonMapper objectMapper) { - super(objectMapper, DEFAULT_JSON_MIME_TYPES); + public JacksonJsonHttpMessageConverter(JsonMapper mapper) { + super(mapper, DEFAULT_JSON_MIME_TYPES); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/smile/JacksonSmileHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/smile/JacksonSmileHttpMessageConverter.java index a6f6c9a9686..c076a3caf1f 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/smile/JacksonSmileHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/smile/JacksonSmileHttpMessageConverter.java @@ -32,8 +32,13 @@ import org.springframework.http.converter.AbstractJacksonHttpMessageConverter; * media type. This can be overridden by setting the * {@link #setSupportedMediaTypes supportedMediaTypes} property. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. + *

The following hints entries are supported: + *

* * @author Sebastien Deleuze * @since 7.0 @@ -51,10 +56,19 @@ public class JacksonSmileHttpMessageConverter extends AbstractJacksonHttpMessage super(SmileMapper.builder(), DEFAULT_SMILE_MIME_TYPES); } + /** + * Construct a new instance with the provided {@link SmileMapper} customized + * with the {@link tools.jackson.databind.JacksonModule}s found by + * {@link MapperBuilder#findModules(ClassLoader)}. + * @see SmileMapper#builder() + */ + public JacksonSmileHttpMessageConverter(SmileMapper.Builder builder) { + super(builder, DEFAULT_SMILE_MIME_TYPES); + } + /** * Construct a new instance with the provided {@link SmileMapper}. * @see SmileMapper#builder() - * @see MapperBuilder#findAndAddModules(ClassLoader) */ public JacksonSmileHttpMessageConverter(SmileMapper mapper) { super(mapper, DEFAULT_SMILE_MIME_TYPES); diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/JacksonXmlHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/JacksonXmlHttpMessageConverter.java index 3213daded78..a8ac78d6d7a 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/JacksonXmlHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/JacksonXmlHttpMessageConverter.java @@ -39,9 +39,6 @@ import org.springframework.util.xml.StaxUtils; * {@code application/*+xml} with {@code UTF-8} character set. This can be overridden by * setting the {@link #setSupportedMediaTypes supportedMediaTypes} property. * - *

The default constructor loads {@link tools.jackson.databind.JacksonModule}s - * found by {@link MapperBuilder#findModules(ClassLoader)}. - * *

The following hint entries are supported: *