Refine Jackson 3 vs 2 setup in CodecConfigurer

Closes gh-35562
This commit is contained in:
rstoyanchev 2025-10-02 17:33:09 +01:00
parent 1333669e2c
commit 8631345b71
4 changed files with 96 additions and 81 deletions

View File

@ -115,6 +115,7 @@ public interface CodecConfigurer {
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be * <p>Note that {@link #maxInMemorySize(int)}, if configured, will be
* applied to the given decoder. * applied to the given decoder.
* @param decoder the decoder instance to use * @param decoder the decoder instance to use
* @since 7.0
* @see org.springframework.http.codec.json.JacksonJsonDecoder * @see org.springframework.http.codec.json.JacksonJsonDecoder
*/ */
void jacksonJsonDecoder(Decoder<?> decoder); void jacksonJsonDecoder(Decoder<?> decoder);
@ -125,12 +126,17 @@ public interface CodecConfigurer {
* applied to the given decoder. * applied to the given decoder.
* @param decoder the decoder instance to use * @param decoder the decoder instance to use
* @see org.springframework.http.codec.json.Jackson2JsonDecoder * @see org.springframework.http.codec.json.Jackson2JsonDecoder
* @deprecated in favor of {@link #jacksonJsonDecoder(Decoder)}.
*/ */
void jackson2JsonDecoder(Decoder<?> decoder); @Deprecated(since = "7.0", forRemoval = true)
default void jackson2JsonDecoder(Decoder<?> decoder) {
jacksonJsonDecoder(decoder);
}
/** /**
* Override the default Jackson 3.x JSON {@code Encoder}. * Override the default Jackson 3.x JSON {@code Encoder}.
* @param encoder the encoder instance to use * @param encoder the encoder instance to use
* @since 7.0
* @see org.springframework.http.codec.json.JacksonJsonEncoder * @see org.springframework.http.codec.json.JacksonJsonEncoder
*/ */
void jacksonJsonEncoder(Encoder<?> encoder); void jacksonJsonEncoder(Encoder<?> encoder);
@ -139,8 +145,12 @@ public interface CodecConfigurer {
* Override the default Jackson 2.x JSON {@code Encoder}. * Override the default Jackson 2.x JSON {@code Encoder}.
* @param encoder the encoder instance to use * @param encoder the encoder instance to use
* @see org.springframework.http.codec.json.Jackson2JsonEncoder * @see org.springframework.http.codec.json.Jackson2JsonEncoder
* @deprecated in favor of {@link #jacksonJsonEncoder(Encoder)}.
*/ */
void jackson2JsonEncoder(Encoder<?> encoder); @Deprecated(since = "7.0", forRemoval = true)
default void jackson2JsonEncoder(Encoder<?> encoder) {
jacksonJsonEncoder(encoder);
}
/** /**
* Override the default Gson {@code Decoder}. * Override the default Gson {@code Decoder}.
@ -161,6 +171,7 @@ public interface CodecConfigurer {
* <p>Note that {@link #maxInMemorySize(int)}, if configured, will be * <p>Note that {@link #maxInMemorySize(int)}, if configured, will be
* applied to the given decoder. * applied to the given decoder.
* @param decoder the decoder instance to use * @param decoder the decoder instance to use
* @since 7.0
* @see JacksonSmileDecoder * @see JacksonSmileDecoder
*/ */
void jacksonSmileDecoder(Decoder<?> decoder); void jacksonSmileDecoder(Decoder<?> decoder);
@ -171,12 +182,17 @@ public interface CodecConfigurer {
* applied to the given decoder. * applied to the given decoder.
* @param decoder the decoder instance to use * @param decoder the decoder instance to use
* @see org.springframework.http.codec.json.Jackson2SmileDecoder * @see org.springframework.http.codec.json.Jackson2SmileDecoder
* @deprecated in favor of {@link #jacksonSmileDecoder(Decoder)}.
*/ */
void jackson2SmileDecoder(Decoder<?> decoder); @Deprecated(since = "7.0", forRemoval = true)
default void jackson2SmileDecoder(Decoder<?> decoder) {
jacksonSmileDecoder(decoder);
}
/** /**
* Override the default Jackson 3.x Smile {@code Encoder}. * Override the default Jackson 3.x Smile {@code Encoder}.
* @param encoder the encoder instance to use * @param encoder the encoder instance to use
* @since 7.0
* @see JacksonSmileEncoder * @see JacksonSmileEncoder
*/ */
void jacksonSmileEncoder(Encoder<?> encoder); void jacksonSmileEncoder(Encoder<?> encoder);
@ -185,8 +201,12 @@ public interface CodecConfigurer {
* Override the default Jackson 2.x Smile {@code Encoder}. * Override the default Jackson 2.x Smile {@code Encoder}.
* @param encoder the encoder instance to use * @param encoder the encoder instance to use
* @see org.springframework.http.codec.json.Jackson2SmileEncoder * @see org.springframework.http.codec.json.Jackson2SmileEncoder
* @deprecated in favor of {@link #jacksonSmileEncoder(Encoder)}.
*/ */
void jackson2SmileEncoder(Encoder<?> encoder); @Deprecated(since = "7.0", forRemoval = true)
default void jackson2SmileEncoder(Encoder<?> encoder) {
jacksonSmileEncoder(encoder);
};
/** /**
* Override the default Protobuf {@code Decoder}. * Override the default Protobuf {@code Decoder}.

View File

@ -132,24 +132,16 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
private @Nullable Decoder<?> jacksonJsonDecoder; private @Nullable Decoder<?> jacksonJsonDecoder;
private @Nullable Decoder<?> jackson2JsonDecoder;
private @Nullable Encoder<?> jacksonJsonEncoder; private @Nullable Encoder<?> jacksonJsonEncoder;
private @Nullable Encoder<?> jackson2JsonEncoder;
private @Nullable Decoder<?> gsonDecoder; private @Nullable Decoder<?> gsonDecoder;
private @Nullable Encoder<?> gsonEncoder; private @Nullable Encoder<?> gsonEncoder;
private @Nullable Encoder<?> jacksonSmileEncoder; private @Nullable Encoder<?> jacksonSmileEncoder;
private @Nullable Encoder<?> jackson2SmileEncoder;
private @Nullable Decoder<?> jacksonSmileDecoder; private @Nullable Decoder<?> jacksonSmileDecoder;
private @Nullable Decoder<?> jackson2SmileDecoder;
private @Nullable Decoder<?> protobufDecoder; private @Nullable Decoder<?> protobufDecoder;
private @Nullable Encoder<?> protobufEncoder; private @Nullable Encoder<?> protobufEncoder;
@ -224,15 +216,11 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
*/ */
protected BaseDefaultCodecs(BaseDefaultCodecs other) { protected BaseDefaultCodecs(BaseDefaultCodecs other) {
this.jacksonJsonDecoder = other.jacksonJsonDecoder; this.jacksonJsonDecoder = other.jacksonJsonDecoder;
this.jackson2JsonDecoder = other.jackson2JsonDecoder;
this.jacksonJsonEncoder = other.jacksonJsonEncoder; this.jacksonJsonEncoder = other.jacksonJsonEncoder;
this.jackson2JsonEncoder = other.jackson2JsonEncoder;
this.gsonDecoder = other.gsonDecoder; this.gsonDecoder = other.gsonDecoder;
this.gsonEncoder = other.gsonEncoder; this.gsonEncoder = other.gsonEncoder;
this.jacksonSmileDecoder = other.jacksonSmileDecoder; this.jacksonSmileDecoder = other.jacksonSmileDecoder;
this.jackson2SmileDecoder = other.jackson2SmileDecoder;
this.jacksonSmileEncoder = other.jacksonSmileEncoder; this.jacksonSmileEncoder = other.jacksonSmileEncoder;
this.jackson2SmileEncoder = other.jackson2SmileEncoder;
this.protobufDecoder = other.protobufDecoder; this.protobufDecoder = other.protobufDecoder;
this.protobufEncoder = other.protobufEncoder; this.protobufEncoder = other.protobufEncoder;
this.jaxb2Decoder = other.jaxb2Decoder; this.jaxb2Decoder = other.jaxb2Decoder;
@ -262,12 +250,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
initObjectReaders(); initObjectReaders();
} }
@Override
public void jackson2JsonDecoder(Decoder<?> decoder) {
this.jackson2JsonDecoder = decoder;
initObjectReaders();
}
@Override @Override
public void jacksonJsonEncoder(Encoder<?> encoder) { public void jacksonJsonEncoder(Encoder<?> encoder) {
this.jacksonJsonEncoder = encoder; this.jacksonJsonEncoder = encoder;
@ -275,13 +257,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
initTypedWriters(); initTypedWriters();
} }
@Override
public void jackson2JsonEncoder(Encoder<?> encoder) {
this.jackson2JsonEncoder = encoder;
initObjectWriters();
initTypedWriters();
}
@Override @Override
public void gsonDecoder(Decoder<?> decoder) { public void gsonDecoder(Decoder<?> decoder) {
this.gsonDecoder = decoder; this.gsonDecoder = decoder;
@ -301,12 +276,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
initObjectReaders(); initObjectReaders();
} }
@Override
public void jackson2SmileDecoder(Decoder<?> decoder) {
this.jackson2SmileDecoder = decoder;
initObjectReaders();
}
@Override @Override
public void jacksonSmileEncoder(Encoder<?> encoder) { public void jacksonSmileEncoder(Encoder<?> encoder) {
this.jacksonSmileEncoder = encoder; this.jacksonSmileEncoder = encoder;
@ -314,13 +283,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
initTypedWriters(); initTypedWriters();
} }
@Override
public void jackson2SmileEncoder(Encoder<?> encoder) {
this.jackson2SmileEncoder = encoder;
initObjectWriters();
initTypedWriters();
}
@Override @Override
public void protobufDecoder(Decoder<?> decoder) { public void protobufDecoder(Decoder<?> decoder) {
this.protobufDecoder = decoder; this.protobufDecoder = decoder;
@ -637,7 +599,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
* Reset and initialize object readers. * Reset and initialize object readers.
* @since 5.3.3 * @since 5.3.3
*/ */
@SuppressWarnings("removal")
protected void initObjectReaders() { protected void initObjectReaders() {
this.objectReaders.clear(); this.objectReaders.clear();
if (!this.registerDefaults) { if (!this.registerDefaults) {
@ -654,25 +615,17 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
(KotlinSerializationProtobufDecoder) this.kotlinSerializationProtobufDecoder : (KotlinSerializationProtobufDecoder) this.kotlinSerializationProtobufDecoder :
new KotlinSerializationProtobufDecoder())); new KotlinSerializationProtobufDecoder()));
} }
if (JACKSON_PRESENT) { if (JACKSON_PRESENT || JACKSON_2_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJacksonJsonDecoder())); addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJacksonJsonDecoder()));
} }
else if (JACKSON_2_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
}
else if (GSON_PRESENT) { else if (GSON_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getGsonDecoder())); addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getGsonDecoder()));
} }
else if (KOTLIN_SERIALIZATION_JSON_PRESENT) { else if (KOTLIN_SERIALIZATION_JSON_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder())); addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getKotlinSerializationJsonDecoder()));
} }
if (JACKSON_SMILE_PRESENT) { if (JACKSON_SMILE_PRESENT || JACKSON_2_SMILE_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(this.jacksonSmileDecoder != null ? addCodec(this.objectReaders, new DecoderHttpMessageReader<>(getJacksonSmileDecoder()));
(JacksonSmileDecoder) this.jacksonSmileDecoder : new JacksonSmileDecoder()));
}
else if (JACKSON_2_SMILE_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(this.jackson2SmileDecoder != null ?
(Jackson2SmileDecoder) this.jackson2SmileDecoder : new Jackson2SmileDecoder()));
} }
if (JAXB_2_PRESENT) { if (JAXB_2_PRESENT) {
addCodec(this.objectReaders, new DecoderHttpMessageReader<>(this.jaxb2Decoder != null ? addCodec(this.objectReaders, new DecoderHttpMessageReader<>(this.jaxb2Decoder != null ?
@ -789,7 +742,6 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
/** /**
* Return "base" object writers only, i.e. common to client and server. * Return "base" object writers only, i.e. common to client and server.
*/ */
@SuppressWarnings("removal")
final List<HttpMessageWriter<?>> getBaseObjectWriters() { final List<HttpMessageWriter<?>> getBaseObjectWriters() {
List<HttpMessageWriter<?>> writers = new ArrayList<>(); List<HttpMessageWriter<?>> writers = new ArrayList<>();
if (KOTLIN_SERIALIZATION_CBOR_PRESENT) { if (KOTLIN_SERIALIZATION_CBOR_PRESENT) {
@ -802,25 +754,17 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
(KotlinSerializationProtobufEncoder) this.kotlinSerializationProtobufEncoder : (KotlinSerializationProtobufEncoder) this.kotlinSerializationProtobufEncoder :
new KotlinSerializationProtobufEncoder())); new KotlinSerializationProtobufEncoder()));
} }
if (JACKSON_PRESENT) { if (JACKSON_PRESENT || JACKSON_2_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getJacksonJsonEncoder())); addCodec(writers, new EncoderHttpMessageWriter<>(getJacksonJsonEncoder()));
} }
else if (JACKSON_2_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
}
else if (GSON_PRESENT) { else if (GSON_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getGsonEncoder())); addCodec(writers, new EncoderHttpMessageWriter<>(getGsonEncoder()));
} }
else if (KOTLIN_SERIALIZATION_JSON_PRESENT) { else if (KOTLIN_SERIALIZATION_JSON_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder())); addCodec(writers, new EncoderHttpMessageWriter<>(getKotlinSerializationJsonEncoder()));
} }
if (JACKSON_SMILE_PRESENT) { if (JACKSON_SMILE_PRESENT || JACKSON_2_SMILE_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(this.jacksonSmileEncoder != null ? addCodec(writers, new EncoderHttpMessageWriter<>(getJacksonSmileEncoder()));
(JacksonSmileEncoder) this.jacksonSmileEncoder : new JacksonSmileEncoder()));
}
else if (JACKSON_2_SMILE_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(this.jackson2SmileEncoder != null ?
(Jackson2SmileEncoder) this.jackson2SmileEncoder : new Jackson2SmileEncoder()));
} }
if (JAXB_2_PRESENT) { if (JAXB_2_PRESENT) {
addCodec(writers, new EncoderHttpMessageWriter<>(this.jaxb2Encoder != null ? addCodec(writers, new EncoderHttpMessageWriter<>(this.jaxb2Encoder != null ?
@ -865,34 +809,55 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
// Accessors for use in subclasses... // Accessors for use in subclasses...
@SuppressWarnings("removal")
protected Decoder<?> getJacksonJsonDecoder() { protected Decoder<?> getJacksonJsonDecoder() {
if (this.jacksonJsonDecoder == null) { if (this.jacksonJsonDecoder == null) {
this.jacksonJsonDecoder = new JacksonJsonDecoder(); if (JACKSON_PRESENT) {
this.jacksonJsonDecoder = new JacksonJsonDecoder();
}
else if (JACKSON_2_PRESENT) {
this.jacksonJsonDecoder = new Jackson2JsonDecoder();
}
else {
throw new IllegalStateException("Jackson not present");
}
} }
return this.jacksonJsonDecoder; return this.jacksonJsonDecoder;
} }
@SuppressWarnings("removal") /**
* Get or initialize a Jackson JSON decoder.
* @deprecated in favor of {@link #getJacksonJsonEncoder()}
*/
@Deprecated(since = "7.0", forRemoval = true)
protected Decoder<?> getJackson2JsonDecoder() { protected Decoder<?> getJackson2JsonDecoder() {
if (this.jackson2JsonDecoder == null) { return getJacksonJsonDecoder();
this.jackson2JsonDecoder = new Jackson2JsonDecoder();
}
return this.jackson2JsonDecoder;
} }
@SuppressWarnings("removal")
protected Encoder<?> getJacksonJsonEncoder() { protected Encoder<?> getJacksonJsonEncoder() {
if (this.jacksonJsonEncoder == null) { if (this.jacksonJsonEncoder == null) {
if (JACKSON_PRESENT) {
this.jacksonJsonEncoder = new JacksonJsonEncoder();
}
else if (JACKSON_2_PRESENT) {
this.jacksonJsonEncoder = new Jackson2JsonEncoder();
}
else {
throw new IllegalStateException("Jackson not present");
}
this.jacksonJsonEncoder = new JacksonJsonEncoder(); this.jacksonJsonEncoder = new JacksonJsonEncoder();
} }
return this.jacksonJsonEncoder; return this.jacksonJsonEncoder;
} }
@SuppressWarnings("removal") /**
* Get or initialize a Jackson JSON encoder.
* @deprecated in favor of {@link #getJacksonJsonEncoder()}
*/
@Deprecated(since = "7.0", forRemoval = true)
protected Encoder<?> getJackson2JsonEncoder() { protected Encoder<?> getJackson2JsonEncoder() {
if (this.jackson2JsonEncoder == null) { return getJacksonJsonEncoder();
this.jackson2JsonEncoder = new Jackson2JsonEncoder();
}
return this.jackson2JsonEncoder;
} }
protected Decoder<?> getGsonDecoder() { protected Decoder<?> getGsonDecoder() {
@ -909,6 +874,38 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs, CodecConfigure
return this.gsonEncoder; return this.gsonEncoder;
} }
@SuppressWarnings("removal")
protected Decoder<?> getJacksonSmileDecoder() {
if (this.jacksonSmileDecoder == null) {
if (JACKSON_PRESENT) {
this.jacksonSmileDecoder = new JacksonSmileDecoder();
}
else if (JACKSON_2_PRESENT) {
this.jacksonSmileDecoder = new Jackson2SmileDecoder();
}
else {
throw new IllegalStateException("Jackson not present");
}
}
return this.jacksonSmileDecoder;
}
@SuppressWarnings("removal")
protected Encoder<?> getJacksonSmileEncoder() {
if (this.jacksonSmileEncoder == null) {
if (JACKSON_PRESENT) {
this.jacksonSmileEncoder = new JacksonSmileEncoder();
}
else if (JACKSON_2_PRESENT) {
this.jacksonSmileEncoder = new Jackson2SmileEncoder();
}
else {
throw new IllegalStateException("Jackson not present");
}
}
return this.jacksonSmileEncoder;
}
protected Decoder<?> getKotlinSerializationJsonDecoder() { protected Decoder<?> getKotlinSerializationJsonDecoder() {
if (this.kotlinSerializationJsonDecoder == null) { if (this.kotlinSerializationJsonDecoder == null) {
this.kotlinSerializationJsonDecoder = new KotlinSerializationJsonDecoder(); this.kotlinSerializationJsonDecoder = new KotlinSerializationJsonDecoder();

View File

@ -53,8 +53,7 @@ class ClientDefaultCodecsImpl extends BaseDefaultCodecs implements ClientCodecCo
protected void extendObjectReaders(List<HttpMessageReader<?>> objectReaders) { protected void extendObjectReaders(List<HttpMessageReader<?>> objectReaders) {
Decoder<?> decoder = (this.sseDecoder != null ? this.sseDecoder : Decoder<?> decoder = (this.sseDecoder != null ? this.sseDecoder :
JACKSON_PRESENT ? getJacksonJsonDecoder() : (JACKSON_PRESENT || JACKSON_2_PRESENT) ? getJacksonJsonDecoder() :
JACKSON_2_PRESENT ? getJackson2JsonDecoder() :
GSON_PRESENT ? getGsonDecoder() : GSON_PRESENT ? getGsonDecoder() :
KOTLIN_SERIALIZATION_JSON_PRESENT ? getKotlinSerializationJsonDecoder() : KOTLIN_SERIALIZATION_JSON_PRESENT ? getKotlinSerializationJsonDecoder() :
null); null);

View File

@ -57,8 +57,7 @@ class ServerDefaultCodecsImpl extends BaseDefaultCodecs implements ServerCodecCo
private @Nullable Encoder<?> getSseEncoder() { private @Nullable Encoder<?> getSseEncoder() {
return this.sseEncoder != null ? this.sseEncoder : return this.sseEncoder != null ? this.sseEncoder :
JACKSON_PRESENT ? getJacksonJsonEncoder() : (JACKSON_PRESENT || JACKSON_2_PRESENT) ? getJacksonJsonEncoder() :
JACKSON_2_PRESENT ? getJackson2JsonEncoder() :
KOTLIN_SERIALIZATION_JSON_PRESENT ? getKotlinSerializationJsonEncoder() : KOTLIN_SERIALIZATION_JSON_PRESENT ? getKotlinSerializationJsonEncoder() :
null; null;
} }