From dc3851df00aa50c209a5be6df59e4d84a3f7c477 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 27 Mar 2017 12:07:18 -0400 Subject: [PATCH] Extract AbstractCodecConfigurer base class Issue: SPR-15247 --- .../http/codec/AbstractCodecConfigurer.java | 400 ++++++++++++++++++ .../http/codec/ServerCodecConfigurer.java | 319 ++------------ .../http/codec/CodecConfigurerTests.java | 289 +++++++++++++ .../codec/ServerCodecConfigurerTests.java | 166 -------- .../config/WebFluxConfigurationSupport.java | 12 +- 5 files changed, 717 insertions(+), 469 deletions(-) create mode 100644 spring-web/src/main/java/org/springframework/http/codec/AbstractCodecConfigurer.java create mode 100644 spring-web/src/test/java/org/springframework/http/codec/CodecConfigurerTests.java diff --git a/spring-web/src/main/java/org/springframework/http/codec/AbstractCodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/AbstractCodecConfigurer.java new file mode 100644 index 00000000000..5198176ef8c --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/codec/AbstractCodecConfigurer.java @@ -0,0 +1,400 @@ +/* + * Copyright 2002-2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.http.codec; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import org.springframework.core.ResolvableType; +import org.springframework.core.codec.ByteArrayDecoder; +import org.springframework.core.codec.ByteArrayEncoder; +import org.springframework.core.codec.ByteBufferDecoder; +import org.springframework.core.codec.ByteBufferEncoder; +import org.springframework.core.codec.CharSequenceEncoder; +import org.springframework.core.codec.DataBufferDecoder; +import org.springframework.core.codec.DataBufferEncoder; +import org.springframework.core.codec.Decoder; +import org.springframework.core.codec.Encoder; +import org.springframework.core.codec.ResourceDecoder; +import org.springframework.core.codec.StringDecoder; +import org.springframework.http.codec.json.Jackson2JsonDecoder; +import org.springframework.http.codec.json.Jackson2JsonEncoder; +import org.springframework.http.codec.xml.Jaxb2XmlDecoder; +import org.springframework.http.codec.xml.Jaxb2XmlEncoder; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +/** + * Base class for client or server codec configurers. + * + * @author Rossen Stoyanchev + * @since 5.0 + */ +public abstract class AbstractCodecConfigurer { + + public static final boolean jackson2Present = + ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", + ServerCodecConfigurer.class.getClassLoader()) && + ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", + ServerCodecConfigurer.class.getClassLoader()); + + public static final boolean jaxb2Present = + ClassUtils.isPresent("javax.xml.bind.Binder", ServerCodecConfigurer.class.getClassLoader()); + + + private final DefaultCodecConfigurer defaultCodecs; + + private final CustomCodecConfigurer customCodecs = new CustomCodecConfigurer(); + + + /** + * Protected constructor with the configurer for default readers and writers. + */ + protected AbstractCodecConfigurer(DefaultCodecConfigurer defaultCodecConfigurer) { + Assert.notNull(defaultCodecConfigurer, "DefaultCodecConfigurer is required."); + this.defaultCodecs = defaultCodecConfigurer; + } + + + /** + * Provide overrides for built-in HTTP message readers or writers. + */ + public DefaultCodecConfigurer defaultCodec() { + return this.defaultCodecs; + } + + /** + * Whether to make default HTTP message reader and writer registrations. + *

By default this is set to {@code "true"}. + */ + public void registerDefaults(boolean registerDefaults) { + this.defaultCodec().setSuppressed(!registerDefaults); + } + + /** + * Register a custom encoder or decoder. + */ + public CustomCodecConfigurer customCodec() { + return this.customCodecs; + } + + + /** + * Prepare a list of HTTP message readers. + */ + public List> getReaders() { + + List> result = new ArrayList<>(); + + addDefaultTypedReaders(result); + addCustomTypedReaders(result); + + addDefaultObjectReaders(result); + addCustomObjectReaders(result); + + defaultCodec().addStringReaderTo(result); + + return result; + } + + /** + * Add built-in, concrete, Java type readers. + */ + protected void addDefaultTypedReaders(List> result) { + defaultCodec().addReaderTo(result, ByteArrayDecoder.class, ByteArrayDecoder::new); + defaultCodec().addReaderTo(result, ByteBufferDecoder.class, ByteBufferDecoder::new); + defaultCodec().addReaderTo(result, DataBufferDecoder.class, DataBufferDecoder::new); + defaultCodec().addReaderTo(result, ResourceDecoder.class, ResourceDecoder::new); + defaultCodec().addStringReaderTextOnlyTo(result); + } + + /** + * Add custom, concrete, Java type readers. + */ + protected void addCustomTypedReaders(List> result) { + customCodec().addTypedReadersTo(result); + } + + /** + * Add built-in, Object-based readers. + */ + protected void addDefaultObjectReaders(List> result) { + if (jaxb2Present) { + defaultCodec().addReaderTo(result, Jaxb2XmlDecoder.class, Jaxb2XmlDecoder::new); + } + if (jackson2Present) { + defaultCodec().addReaderTo(result, Jackson2JsonDecoder.class, Jackson2JsonDecoder::new); + } + } + + /** + * Add custom, Object-based readers. + */ + protected void addCustomObjectReaders(List> result) { + customCodec().addObjectReadersTo(result); + } + + + /** + * Prepare a list of HTTP message writers. + */ + public List> getWriters() { + + List> result = new ArrayList<>(); + + addDefaultTypedWriter(result); + addCustomTypedWriter(result); + + addDefaultObjectWriters(result); + addCustomObjectWriters(result); + + // String + "*/*" + defaultCodec().addStringWriterTo(result); + + return result; + } + + /** + * Add built-in, concrete, Java type readers. + */ + protected void addDefaultTypedWriter(List> result) { + defaultCodec().addWriterTo(result, ByteArrayEncoder.class, ByteArrayEncoder::new); + defaultCodec().addWriterTo(result, ByteBufferEncoder.class, ByteBufferEncoder::new); + defaultCodec().addWriterTo(result, DataBufferEncoder.class, DataBufferEncoder::new); + defaultCodec().addWriterTo(result, ResourceHttpMessageWriter::new); + defaultCodec().addStringWriterTextPlainOnlyTo(result); + } + + /** + * Add custom, concrete, Java type readers. + */ + protected void addCustomTypedWriter(List> result) { + customCodec().addTypedWritersTo(result); + } + + /** + * Add built-in, Object-based readers. + */ + protected void addDefaultObjectWriters(List> result) { + if (jaxb2Present) { + defaultCodec().addWriterTo(result, Jaxb2XmlEncoder.class, Jaxb2XmlEncoder::new); + } + if (jackson2Present) { + defaultCodec().addWriterTo(result, Jackson2JsonEncoder.class, Jackson2JsonEncoder::new); + } + } + + /** + * Add custom, Object-based readers. + */ + protected void addCustomObjectWriters(List> result) { + customCodec().addObjectWritersTo(result); + } + + + + /** + * A registry and a factory for built-in HTTP message readers and writers. + */ + public static class DefaultCodecConfigurer { + + private boolean suppressed = false; + + private final Map, HttpMessageReader> readers = new HashMap<>(); + + private final Map, HttpMessageWriter> writers = new HashMap<>(); + + + /** + * Override the default Jackson {@code Decoder}. + * @param decoder the decoder to use + */ + public void jackson2Decoder(Jackson2JsonDecoder decoder) { + this.readers.put(Jackson2JsonDecoder.class, new DecoderHttpMessageReader<>(decoder)); + } + + /** + * Override the default Jackson {@code Encoder} for JSON. + * @param encoder the encoder to use + */ + public void jackson2Encoder(Jackson2JsonEncoder encoder) { + this.writers.put(Jackson2JsonEncoder.class, new EncoderHttpMessageWriter<>(encoder)); + } + + + // Accessors for internal use... + + + protected Map, HttpMessageReader> getReaders() { + return this.readers; + } + + protected Map, HttpMessageWriter> getWriters() { + return this.writers; + } + + private void setSuppressed(boolean suppressed) { + this.suppressed = suppressed; + } + + + // Protected methods for building a list of default readers or writers... + + + protected > void addReaderTo(List> result, + Class key, Supplier fallback) { + + addReaderTo(result, () -> findDecoderReader(key, fallback)); + } + + protected void addReaderTo(List> result, + Supplier> reader) { + + if (!this.suppressed) { + result.add(reader.get()); + } + } + + protected > DecoderHttpMessageReader findDecoderReader( + Class decoderType, Supplier fallback) { + + DecoderHttpMessageReader reader = (DecoderHttpMessageReader) this.readers.get(decoderType); + return reader != null ? reader : new DecoderHttpMessageReader<>(fallback.get()); + } + + @SuppressWarnings("unchecked") + protected HttpMessageReader findReader(Class key, Supplier> fallback) { + return this.readers.containsKey(key) ? this.readers.get(key) : fallback.get(); + } + + + protected > void addWriterTo(List> result, + Class key, Supplier fallback) { + + addWriterTo(result, () -> findEncoderWriter(key, fallback)); + } + + protected void addWriterTo(List> result, + Supplier> writer) { + + if (!this.suppressed) { + result.add(writer.get()); + } + } + + protected > EncoderHttpMessageWriter findEncoderWriter( + Class encoderType, Supplier fallback) { + + EncoderHttpMessageWriter writer = (EncoderHttpMessageWriter) this.writers.get(encoderType); + return writer != null ? writer : new EncoderHttpMessageWriter<>(fallback.get()); + } + + @SuppressWarnings("unchecked") + protected HttpMessageWriter findWriter(Class key, Supplier> fallback) { + return this.writers.containsKey(key) ? this.writers.get(key) : fallback.get(); + } + + + protected void addStringReaderTextOnlyTo(List> result) { + addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly(true))); + } + + protected void addStringReaderTo(List> result) { + addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true))); + } + + protected void addStringWriterTextPlainOnlyTo(List> result) { + addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly())); + } + + protected void addStringWriterTo(List> result) { + addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes())); + } + } + + /** + * Registry and container for custom HTTP message readers and writers. + */ + public static class CustomCodecConfigurer { + + private final List> typedReaders = new ArrayList<>(); + + private final List> typedWriters = new ArrayList<>(); + + private final List> objectReaders = new ArrayList<>(); + + private final List> objectWriters = new ArrayList<>(); + + + /** + * Add a custom {@code Decoder} internally wrapped with + * {@link DecoderHttpMessageReader}). + */ + public void decoder(Decoder decoder) { + reader(new DecoderHttpMessageReader<>(decoder)); + } + + /** + * Add a custom {@code Encoder}, internally wrapped with + * {@link EncoderHttpMessageWriter}. + */ + public void encoder(Encoder encoder) { + writer(new EncoderHttpMessageWriter<>(encoder)); + } + + /** + * Add a custom {@link HttpMessageReader}. For readers of type + * {@link DecoderHttpMessageReader} consider using the shortcut + * {@link #decoder(Decoder)} instead. + */ + public void reader(HttpMessageReader reader) { + boolean canReadToObject = reader.canRead(ResolvableType.forClass(Object.class), null); + (canReadToObject ? this.objectReaders : this.typedReaders).add(reader); + } + + /** + * Add a custom {@link HttpMessageWriter}. For readers of type + * {@link EncoderHttpMessageWriter} consider using the shortcut + * {@link #encoder(Encoder)} instead. + */ + public void writer(HttpMessageWriter writer) { + boolean canWriteObject = writer.canWrite(ResolvableType.forClass(Object.class), null); + (canWriteObject ? this.objectWriters : this.typedWriters).add(writer); + } + + + // Internal methods for building a list of custom readers or writers... + + protected void addTypedReadersTo(List> result) { + result.addAll(this.typedReaders); + } + + protected void addObjectReadersTo(List> result) { + result.addAll(this.objectReaders); + } + + protected void addTypedWritersTo(List> result) { + result.addAll(this.typedWriters); + } + + protected void addObjectWritersTo(List> result) { + result.addAll(this.objectWriters); + } + } +} diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java index 6f5c58563ef..3302cf37f90 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java @@ -15,343 +15,78 @@ */ package org.springframework.http.codec; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import org.springframework.core.ResolvableType; -import org.springframework.core.codec.ByteArrayDecoder; -import org.springframework.core.codec.ByteArrayEncoder; -import org.springframework.core.codec.ByteBufferDecoder; -import org.springframework.core.codec.ByteBufferEncoder; -import org.springframework.core.codec.CharSequenceEncoder; -import org.springframework.core.codec.DataBufferDecoder; -import org.springframework.core.codec.DataBufferEncoder; -import org.springframework.core.codec.Decoder; import org.springframework.core.codec.Encoder; -import org.springframework.core.codec.ResourceDecoder; -import org.springframework.core.codec.StringDecoder; -import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.http.codec.json.Jackson2JsonEncoder; -import org.springframework.http.codec.xml.Jaxb2XmlDecoder; -import org.springframework.http.codec.xml.Jaxb2XmlEncoder; -import org.springframework.util.ClassUtils; /** * Helps to configure a list of server-side HTTP message readers and writers * with support for built-in defaults and options to register additional custom * readers and writers via {@link #customCodec()}. * - *

The built-in defaults include basic data types such as - * {@link Byte byte[]}, {@link java.nio.ByteBuffer ByteBuffer}, - * {@link org.springframework.core.io.buffer.DataBuffer DataBuffer}, - * {@link String}, {@link org.springframework.core.io.Resource Resource}, - * in addition to JAXB2 and Jackson 2 based on classpath detection, as well as - * support for Server-Sent Events. There are options to {@link #defaultCodec() - * override} some of the defaults or to have them + *

The built-in defaults include basic data types such as various byte + * representations, resources, strings, forms, but also others like JAXB2 and + * Jackson 2 based on classpath detection. There are options to + * {@link #defaultCodec() override} some of the defaults or to have them * {@link #registerDefaults(boolean) turned off} completely. * * @author Rossen Stoyanchev * @since 5.0 */ -public class ServerCodecConfigurer { +public class ServerCodecConfigurer extends AbstractCodecConfigurer { - private static final boolean jackson2Present = - ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", - ServerCodecConfigurer.class.getClassLoader()) && - ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", - ServerCodecConfigurer.class.getClassLoader()); - private static final boolean jaxb2Present = - ClassUtils.isPresent("javax.xml.bind.Binder", ServerCodecConfigurer.class.getClassLoader()); - - - private final DefaultCodecConfigurer defaultCodecs = new DefaultCodecConfigurer(); - - private final CustomCodecConfigurer customCodecs = new CustomCodecConfigurer(); - - - /** - * Provide overrides for built-in HTTP message readers and writers. - */ - public DefaultCodecConfigurer defaultCodec() { - return this.defaultCodecs; + public ServerCodecConfigurer() { + super(new ServerDefaultCodecConfigurer()); } - /** - * Whether to make default HTTP message reader and writer registrations. - *

By default this is set to {@code "true"}. - */ - public void registerDefaults(boolean register) { - this.defaultCodec().setSuppressed(!register); - } - /** - * Register a custom encoder or decoder. - */ - public CustomCodecConfigurer customCodec() { - return this.customCodecs; + @Override + public ServerDefaultCodecConfigurer defaultCodec() { + return (ServerDefaultCodecConfigurer) super.defaultCodec(); } - /** - * Prepare a list of HTTP message readers. - */ - public List> getReaders() { - - // Built-in, concrete Java type readers - List> result = new ArrayList<>(); - this.defaultCodecs.addReaderTo(result, ByteArrayDecoder.class, ByteArrayDecoder::new); - this.defaultCodecs.addReaderTo(result, ByteBufferDecoder.class, ByteBufferDecoder::new); - this.defaultCodecs.addReaderTo(result, DataBufferDecoder.class, DataBufferDecoder::new); - this.defaultCodecs.addReaderTo(result, ResourceDecoder.class, ResourceDecoder::new); - this.defaultCodecs.addStringReaderTextOnlyTo(result); - - this.defaultCodecs.addReaderTo(result, FormHttpMessageReader::new); - - // Custom, concrete Java type readers - this.customCodecs.addTypedReadersTo(result); - - // Built-in, Object-based readers - if (jaxb2Present) { - this.defaultCodecs.addReaderTo(result, Jaxb2XmlDecoder.class, Jaxb2XmlDecoder::new); - } - if (jackson2Present) { - this.defaultCodecs.addReaderTo(result, Jackson2JsonDecoder.class, Jackson2JsonDecoder::new); - } - - // Custom, Object-based readers - this.customCodecs.addObjectReadersTo(result); - - // Potentially overlapping Java types + "*/*" - this.defaultCodecs.addStringReaderTo(result); - return result; + protected void addDefaultTypedReaders(List> result) { + super.addDefaultTypedReaders(result); + defaultCodec().addReaderTo(result, FormHttpMessageReader::new); } - /** - * Prepare a list of HTTP message writers. - */ - public List> getWriters() { - - // Built-in, concrete Java type readers - List> result = new ArrayList<>(); - this.defaultCodecs.addWriterTo(result, ByteArrayEncoder.class, ByteArrayEncoder::new); - this.defaultCodecs.addWriterTo(result, ByteBufferEncoder.class, ByteBufferEncoder::new); - this.defaultCodecs.addWriterTo(result, DataBufferEncoder.class, DataBufferEncoder::new); - this.defaultCodecs.addWriterTo(result, ResourceHttpMessageWriter::new); - this.defaultCodecs.addStringWriterTextPlainOnlyTo(result); - // Custom, concrete Java type readers - this.customCodecs.addTypedWritersTo(result); - - // Built-in, Object-based readers - if (jaxb2Present) { - this.defaultCodecs.addWriterTo(result, Jaxb2XmlEncoder.class, Jaxb2XmlEncoder::new); - } - if (jackson2Present) { - this.defaultCodecs.addWriterTo(result, Jackson2JsonEncoder.class, Jackson2JsonEncoder::new); - } - this.defaultCodecs.addSseWriterTo(result); - - // Custom, Object-based readers - this.customCodecs.addObjectWritersTo(result); - - // Potentially overlapping Java types + "*/*" - this.defaultCodecs.addStringWriterTo(result); - return result; + protected void addDefaultObjectWriters(List> result) { + super.addDefaultObjectWriters(result); + defaultCodec().addServerSentEventWriterTo(result); } /** - * A registry and a factory for built-in HTTP message readers and writers. + * Extension of {@code DefaultCodecConfigurer} with extra server options. */ - public static class DefaultCodecConfigurer { - - private boolean suppressed = false; - - private final Map, HttpMessageReader> readers = new HashMap<>(); - - private final Map, HttpMessageWriter> writers = new HashMap<>(); - - - /** - * Override the default Jackson {@code Decoder}. - * @param decoder the decoder to use - */ - public void jackson2Decoder(Jackson2JsonDecoder decoder) { - this.readers.put(Jackson2JsonDecoder.class, new DecoderHttpMessageReader<>(decoder)); - } - - /** - * Override the default Jackson {@code Encoder} for JSON. Also used for - * SSE unless further overridden via {@link #sse(Encoder)}. - * @param encoder the encoder to use - */ - public void jackson2Encoder(Jackson2JsonEncoder encoder) { - this.writers.put(Jackson2JsonEncoder.class, new EncoderHttpMessageWriter<>(encoder)); - } + public static class ServerDefaultCodecConfigurer extends DefaultCodecConfigurer { /** * Configure the {@code Encoder} to use for Server-Sent Events. *

By default the {@link #jackson2Encoder} override is used for SSE. * @param encoder the encoder to use */ - public void sse(Encoder encoder) { + public void serverSentEventEncoder(Encoder encoder) { HttpMessageWriter writer = new ServerSentEventHttpMessageWriter(encoder); - this.writers.put(ServerSentEventHttpMessageWriter.class, writer); + getWriters().put(ServerSentEventHttpMessageWriter.class, writer); } // Internal methods for building a list of default readers or writers... - private void setSuppressed(boolean suppressed) { - this.suppressed = suppressed; - } - - private > void addReaderTo(List> result, - Class key, Supplier fallback) { - - addReaderTo(result, () -> findReader(key, fallback)); - } - - private void addReaderTo(List> result, - Supplier> reader) { - - if (!this.suppressed) { - result.add(reader.get()); - } - } - - private > DecoderHttpMessageReader findReader( - Class key, Supplier fallback) { - - DecoderHttpMessageReader reader = (DecoderHttpMessageReader) this.readers.get(key); - return reader != null ? reader : new DecoderHttpMessageReader<>(fallback.get()); - } - - - private > void addWriterTo(List> result, - Class key, Supplier fallback) { - - addWriterTo(result, () -> findWriter(key, fallback)); - } - - private void addWriterTo(List> result, - Supplier> writer) { - - if (!this.suppressed) { - result.add(writer.get()); - } - } - - private > EncoderHttpMessageWriter findWriter( - Class key, Supplier fallback) { - - EncoderHttpMessageWriter writer = (EncoderHttpMessageWriter) this.writers.get(key); - return writer != null ? writer : new EncoderHttpMessageWriter<>(fallback.get()); - } - - - private void addStringReaderTextOnlyTo(List> result) { - addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly(true))); - } - - private void addStringReaderTo(List> result) { - addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true))); - } - - private void addStringWriterTextPlainOnlyTo(List> result) { - addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly())); - } - - private void addStringWriterTo(List> result) { - addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes())); - } - - private void addSseWriterTo(List> result) { - addWriterTo(result, () -> { - HttpMessageWriter writer = this.writers.get(ServerSentEventHttpMessageWriter.class); - if (writer != null) { - return writer; - } + private void addServerSentEventWriterTo(List> result) { + addWriterTo(result, () -> findWriter(ServerSentEventHttpMessageWriter.class, () -> { + Encoder encoder = null; if (jackson2Present) { - return new ServerSentEventHttpMessageWriter( - findWriter(Jackson2JsonEncoder.class, Jackson2JsonEncoder::new).getEncoder()); + encoder = findEncoderWriter( + Jackson2JsonEncoder.class, Jackson2JsonEncoder::new).getEncoder(); } - return new ServerSentEventHttpMessageWriter(); - }); - } - } - - /** - * Registry and container for custom HTTP message readers and writers. - */ - public static class CustomCodecConfigurer { - - private final List> typedReaders = new ArrayList<>(); - - private final List> typedWriters = new ArrayList<>(); - - private final List> objectReaders = new ArrayList<>(); - - private final List> objectWriters = new ArrayList<>(); - - - /** - * Add a custom {@code Decoder} internally wrapped with - * {@link DecoderHttpMessageReader}). - */ - public void decoder(Decoder decoder) { - reader(new DecoderHttpMessageReader<>(decoder)); - } - - /** - * Add a custom {@code Encoder}, internally wrapped with - * {@link EncoderHttpMessageWriter}. - */ - public void encoder(Encoder encoder) { - writer(new EncoderHttpMessageWriter<>(encoder)); - } - - /** - * Add a custom {@link HttpMessageReader}. For readers of type - * {@link DecoderHttpMessageReader} consider using the shortcut - * {@link #decoder(Decoder)} instead. - */ - public void reader(HttpMessageReader reader) { - boolean canReadToObject = reader.canRead(ResolvableType.forClass(Object.class), null); - (canReadToObject ? this.objectReaders : this.typedReaders).add(reader); - } - - /** - * Add a custom {@link HttpMessageWriter}. For readers of type - * {@link EncoderHttpMessageWriter} consider using the shortcut - * {@link #encoder(Encoder)} instead. - */ - public void writer(HttpMessageWriter writer) { - boolean canWriteObject = writer.canWrite(ResolvableType.forClass(Object.class), null); - (canWriteObject ? this.objectWriters : this.typedWriters).add(writer); - } - - - // Internal methods for building a list of custom readers or writers... - - private void addTypedReadersTo(List> result) { - result.addAll(this.typedReaders); - } - - private void addObjectReadersTo(List> result) { - result.addAll(this.objectReaders); - } - - private void addTypedWritersTo(List> result) { - result.addAll(this.typedWriters); - } - - private void addObjectWritersTo(List> result) { - result.addAll(this.objectWriters); + return new ServerSentEventHttpMessageWriter(encoder); + })); } } diff --git a/spring-web/src/test/java/org/springframework/http/codec/CodecConfigurerTests.java b/spring-web/src/test/java/org/springframework/http/codec/CodecConfigurerTests.java new file mode 100644 index 00000000000..8c57c69f2f2 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/http/codec/CodecConfigurerTests.java @@ -0,0 +1,289 @@ +/* + * Copyright 2002-2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.http.codec; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Test; + +import org.springframework.core.ResolvableType; +import org.springframework.core.codec.ByteArrayDecoder; +import org.springframework.core.codec.ByteArrayEncoder; +import org.springframework.core.codec.ByteBufferDecoder; +import org.springframework.core.codec.ByteBufferEncoder; +import org.springframework.core.codec.CharSequenceEncoder; +import org.springframework.core.codec.DataBufferDecoder; +import org.springframework.core.codec.DataBufferEncoder; +import org.springframework.core.codec.Decoder; +import org.springframework.core.codec.Encoder; +import org.springframework.core.codec.ResourceDecoder; +import org.springframework.core.codec.StringDecoder; +import org.springframework.http.MediaType; +import org.springframework.http.codec.json.Jackson2JsonDecoder; +import org.springframework.http.codec.json.Jackson2JsonEncoder; +import org.springframework.http.codec.xml.Jaxb2XmlDecoder; +import org.springframework.http.codec.xml.Jaxb2XmlEncoder; +import org.springframework.util.MimeTypeUtils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.core.ResolvableType.forClass; + +/** + * Unit tests for {@link ServerCodecConfigurer}. + * @author Rossen Stoyanchev + */ +public class CodecConfigurerTests { + + private final TestCodecConfigurer configurer = new TestCodecConfigurer(); + + private final AtomicInteger index = new AtomicInteger(0); + + + @Test + public void defaultReaders() throws Exception { + List> readers = this.configurer.getReaders(); + assertEquals(8, readers.size()); + assertEquals(ByteArrayDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(ByteBufferDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(DataBufferDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(ResourceDecoder.class, getNextDecoder(readers).getClass()); + assertStringDecoder(getNextDecoder(readers), true); + assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass()); + assertStringDecoder(getNextDecoder(readers), false); + } + + @Test + public void defaultWriters() throws Exception { + List> writers = this.configurer.getWriters(); + assertEquals(8, writers.size()); + assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(ByteBufferEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(DataBufferEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(ResourceHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass()); + assertStringEncoder(getNextEncoder(writers), true); + assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(Jackson2JsonEncoder.class, getNextEncoder(writers).getClass()); + assertStringEncoder(getNextEncoder(writers), false); + } + + @Test + public void defaultAndCustomReaders() throws Exception { + + Decoder customDecoder1 = mock(Decoder.class); + Decoder customDecoder2 = mock(Decoder.class); + + when(customDecoder1.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customDecoder2.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + HttpMessageReader customReader1 = mock(HttpMessageReader.class); + HttpMessageReader customReader2 = mock(HttpMessageReader.class); + + when(customReader1.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customReader2.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + this.configurer.customCodec().decoder(customDecoder1); + this.configurer.customCodec().decoder(customDecoder2); + + this.configurer.customCodec().reader(customReader1); + this.configurer.customCodec().reader(customReader2); + + List> readers = this.configurer.getReaders(); + + assertEquals(12, readers.size()); + assertEquals(ByteArrayDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(ByteBufferDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(DataBufferDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(ResourceDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(StringDecoder.class, getNextDecoder(readers).getClass()); + assertSame(customDecoder1, getNextDecoder(readers)); + assertSame(customReader1, readers.get(this.index.getAndIncrement())); + assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass()); + assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass()); + assertSame(customDecoder2, getNextDecoder(readers)); + assertSame(customReader2, readers.get(this.index.getAndIncrement())); + assertEquals(StringDecoder.class, getNextDecoder(readers).getClass()); + } + + @Test + public void defaultAndCustomWriters() throws Exception { + + Encoder customEncoder1 = mock(Encoder.class); + Encoder customEncoder2 = mock(Encoder.class); + + when(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + HttpMessageWriter customWriter1 = mock(HttpMessageWriter.class); + HttpMessageWriter customWriter2 = mock(HttpMessageWriter.class); + + when(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + this.configurer.customCodec().encoder(customEncoder1); + this.configurer.customCodec().encoder(customEncoder2); + + this.configurer.customCodec().writer(customWriter1); + this.configurer.customCodec().writer(customWriter2); + + List> writers = this.configurer.getWriters(); + + assertEquals(12, writers.size()); + assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(ByteBufferEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(DataBufferEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(ResourceHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass()); + assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass()); + assertSame(customEncoder1, getNextEncoder(writers)); + assertSame(customWriter1, writers.get(this.index.getAndIncrement())); + assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass()); + assertEquals(Jackson2JsonEncoder.class, getNextEncoder(writers).getClass()); + assertSame(customEncoder2, getNextEncoder(writers)); + assertSame(customWriter2, writers.get(this.index.getAndIncrement())); + assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass()); + } + + @Test + public void defaultsOffCustomReaders() throws Exception { + + Decoder customDecoder1 = mock(Decoder.class); + Decoder customDecoder2 = mock(Decoder.class); + + when(customDecoder1.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customDecoder2.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + HttpMessageReader customReader1 = mock(HttpMessageReader.class); + HttpMessageReader customReader2 = mock(HttpMessageReader.class); + + when(customReader1.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customReader2.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + this.configurer.customCodec().decoder(customDecoder1); + this.configurer.customCodec().decoder(customDecoder2); + + this.configurer.customCodec().reader(customReader1); + this.configurer.customCodec().reader(customReader2); + + this.configurer.registerDefaults(false); + + List> readers = this.configurer.getReaders(); + + assertEquals(4, readers.size()); + assertSame(customDecoder1, getNextDecoder(readers)); + assertSame(customReader1, readers.get(this.index.getAndIncrement())); + assertSame(customDecoder2, getNextDecoder(readers)); + assertSame(customReader2, readers.get(this.index.getAndIncrement())); + } + + @Test + public void defaultsOffWithCustomWriters() throws Exception { + + Encoder customEncoder1 = mock(Encoder.class); + Encoder customEncoder2 = mock(Encoder.class); + + when(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + HttpMessageWriter customWriter1 = mock(HttpMessageWriter.class); + HttpMessageWriter customWriter2 = mock(HttpMessageWriter.class); + + when(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(false); + when(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(true); + + this.configurer.customCodec().encoder(customEncoder1); + this.configurer.customCodec().encoder(customEncoder2); + + this.configurer.customCodec().writer(customWriter1); + this.configurer.customCodec().writer(customWriter2); + + this.configurer.registerDefaults(false); + + List> writers = this.configurer.getWriters(); + + assertEquals(4, writers.size()); + assertSame(customEncoder1, getNextEncoder(writers)); + assertSame(customWriter1, writers.get(this.index.getAndIncrement())); + assertSame(customEncoder2, getNextEncoder(writers)); + assertSame(customWriter2, writers.get(this.index.getAndIncrement())); + } + + @Test + public void jackson2DecoderOverride() throws Exception { + + Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(); + this.configurer.defaultCodec().jackson2Decoder(decoder); + + assertSame(decoder, this.configurer.getReaders().stream() + .filter(writer -> writer instanceof DecoderHttpMessageReader) + .map(writer -> ((DecoderHttpMessageReader) writer).getDecoder()) + .filter(e -> Jackson2JsonDecoder.class.equals(e.getClass())) + .findFirst() + .filter(e -> e == decoder).orElse(null)); + } + + @Test + public void jackson2EncoderOverride() throws Exception { + + Jackson2JsonEncoder encoder = new Jackson2JsonEncoder(); + this.configurer.defaultCodec().jackson2Encoder(encoder); + + assertSame(encoder, this.configurer.getWriters().stream() + .filter(writer -> writer instanceof EncoderHttpMessageWriter) + .map(writer -> ((EncoderHttpMessageWriter) writer).getEncoder()) + .filter(e -> Jackson2JsonEncoder.class.equals(e.getClass())) + .findFirst() + .filter(e -> e == encoder).orElse(null)); + } + + + private Decoder getNextDecoder(List> readers) { + HttpMessageReader reader = readers.get(this.index.getAndIncrement()); + assertEquals(DecoderHttpMessageReader.class, reader.getClass()); + return ((DecoderHttpMessageReader) reader).getDecoder(); + } + + private Encoder getNextEncoder(List> writers) { + HttpMessageWriter writer = writers.get(this.index.getAndIncrement()); + assertEquals(EncoderHttpMessageWriter.class, writer.getClass()); + return ((EncoderHttpMessageWriter) writer).getEncoder(); + } + + private void assertStringDecoder(Decoder decoder, boolean textOnly) { + assertEquals(StringDecoder.class, decoder.getClass()); + assertTrue(decoder.canDecode(forClass(String.class), MimeTypeUtils.TEXT_PLAIN)); + assertEquals(!textOnly, decoder.canDecode(forClass(String.class), MediaType.TEXT_EVENT_STREAM)); + } + + private void assertStringEncoder(Encoder encoder, boolean textOnly) { + assertEquals(CharSequenceEncoder.class, encoder.getClass()); + assertTrue(encoder.canEncode(forClass(String.class), MimeTypeUtils.TEXT_PLAIN)); + assertEquals(!textOnly, encoder.canEncode(forClass(String.class), MediaType.TEXT_EVENT_STREAM)); + } + + + private static class TestCodecConfigurer extends AbstractCodecConfigurer { + + private TestCodecConfigurer() { + super(new DefaultCodecConfigurer()); + } + } + +} diff --git a/spring-web/src/test/java/org/springframework/http/codec/ServerCodecConfigurerTests.java b/spring-web/src/test/java/org/springframework/http/codec/ServerCodecConfigurerTests.java index d33087b7230..d98853b2159 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/ServerCodecConfigurerTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/ServerCodecConfigurerTests.java @@ -20,7 +20,6 @@ import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; -import org.springframework.core.ResolvableType; import org.springframework.core.codec.ByteArrayDecoder; import org.springframework.core.codec.ByteArrayEncoder; import org.springframework.core.codec.ByteBufferDecoder; @@ -43,8 +42,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import static org.springframework.core.ResolvableType.forClass; /** @@ -88,175 +85,12 @@ public class ServerCodecConfigurerTests { assertStringEncoder(getNextEncoder(writers), false); } - @Test - public void defaultAndCustomReaders() throws Exception { - - Decoder customDecoder1 = mock(Decoder.class); - Decoder customDecoder2 = mock(Decoder.class); - - when(customDecoder1.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customDecoder2.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - HttpMessageReader customReader1 = mock(HttpMessageReader.class); - HttpMessageReader customReader2 = mock(HttpMessageReader.class); - - when(customReader1.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customReader2.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - this.configurer.customCodec().decoder(customDecoder1); - this.configurer.customCodec().decoder(customDecoder2); - - this.configurer.customCodec().reader(customReader1); - this.configurer.customCodec().reader(customReader2); - - List> readers = this.configurer.getReaders(); - - assertEquals(13, readers.size()); - assertEquals(ByteArrayDecoder.class, getNextDecoder(readers).getClass()); - assertEquals(ByteBufferDecoder.class, getNextDecoder(readers).getClass()); - assertEquals(DataBufferDecoder.class, getNextDecoder(readers).getClass()); - assertEquals(ResourceDecoder.class, getNextDecoder(readers).getClass()); - assertEquals(StringDecoder.class, getNextDecoder(readers).getClass()); - assertEquals(FormHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass()); - assertSame(customDecoder1, getNextDecoder(readers)); - assertSame(customReader1, readers.get(this.index.getAndIncrement())); - assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass()); - assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass()); - assertSame(customDecoder2, getNextDecoder(readers)); - assertSame(customReader2, readers.get(this.index.getAndIncrement())); - assertEquals(StringDecoder.class, getNextDecoder(readers).getClass()); - } - - @Test - public void defaultAndCustomWriters() throws Exception { - - Encoder customEncoder1 = mock(Encoder.class); - Encoder customEncoder2 = mock(Encoder.class); - - when(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - HttpMessageWriter customWriter1 = mock(HttpMessageWriter.class); - HttpMessageWriter customWriter2 = mock(HttpMessageWriter.class); - - when(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - this.configurer.customCodec().encoder(customEncoder1); - this.configurer.customCodec().encoder(customEncoder2); - - this.configurer.customCodec().writer(customWriter1); - this.configurer.customCodec().writer(customWriter2); - - List> writers = this.configurer.getWriters(); - - assertEquals(13, writers.size()); - assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass()); - assertEquals(ByteBufferEncoder.class, getNextEncoder(writers).getClass()); - assertEquals(DataBufferEncoder.class, getNextEncoder(writers).getClass()); - assertEquals(ResourceHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass()); - assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass()); - assertSame(customEncoder1, getNextEncoder(writers)); - assertSame(customWriter1, writers.get(this.index.getAndIncrement())); - assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass()); - assertEquals(Jackson2JsonEncoder.class, getNextEncoder(writers).getClass()); - assertEquals(ServerSentEventHttpMessageWriter.class, writers.get(this.index.getAndIncrement()).getClass()); - assertSame(customEncoder2, getNextEncoder(writers)); - assertSame(customWriter2, writers.get(this.index.getAndIncrement())); - assertEquals(CharSequenceEncoder.class, getNextEncoder(writers).getClass()); - } - - @Test - public void defaultsOffCustomReaders() throws Exception { - - Decoder customDecoder1 = mock(Decoder.class); - Decoder customDecoder2 = mock(Decoder.class); - - when(customDecoder1.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customDecoder2.canDecode(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - HttpMessageReader customReader1 = mock(HttpMessageReader.class); - HttpMessageReader customReader2 = mock(HttpMessageReader.class); - - when(customReader1.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customReader2.canRead(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - this.configurer.customCodec().decoder(customDecoder1); - this.configurer.customCodec().decoder(customDecoder2); - - this.configurer.customCodec().reader(customReader1); - this.configurer.customCodec().reader(customReader2); - - this.configurer.registerDefaults(false); - - List> readers = this.configurer.getReaders(); - - assertEquals(4, readers.size()); - assertSame(customDecoder1, getNextDecoder(readers)); - assertSame(customReader1, readers.get(this.index.getAndIncrement())); - assertSame(customDecoder2, getNextDecoder(readers)); - assertSame(customReader2, readers.get(this.index.getAndIncrement())); - } - - @Test - public void defaultsOffWithCustomWriters() throws Exception { - - Encoder customEncoder1 = mock(Encoder.class); - Encoder customEncoder2 = mock(Encoder.class); - - when(customEncoder1.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customEncoder2.canEncode(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - HttpMessageWriter customWriter1 = mock(HttpMessageWriter.class); - HttpMessageWriter customWriter2 = mock(HttpMessageWriter.class); - - when(customWriter1.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(false); - when(customWriter2.canWrite(ResolvableType.forClass(Object.class), null)).thenReturn(true); - - this.configurer.customCodec().encoder(customEncoder1); - this.configurer.customCodec().encoder(customEncoder2); - - this.configurer.customCodec().writer(customWriter1); - this.configurer.customCodec().writer(customWriter2); - - this.configurer.registerDefaults(false); - - List> writers = this.configurer.getWriters(); - - assertEquals(4, writers.size()); - assertSame(customEncoder1, getNextEncoder(writers)); - assertSame(customWriter1, writers.get(this.index.getAndIncrement())); - assertSame(customEncoder2, getNextEncoder(writers)); - assertSame(customWriter2, writers.get(this.index.getAndIncrement())); - } - - @Test - public void jackson2DecoderOverride() throws Exception { - - Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(); - this.configurer.defaultCodec().jackson2Decoder(decoder); - - assertSame(decoder, this.configurer.getReaders().stream() - .filter(writer -> writer instanceof DecoderHttpMessageReader) - .map(writer -> ((DecoderHttpMessageReader) writer).getDecoder()) - .filter(e -> Jackson2JsonDecoder.class.equals(e.getClass())) - .findFirst() - .filter(e -> e == decoder).orElse(null)); - } - @Test public void jackson2EncoderOverride() throws Exception { Jackson2JsonEncoder encoder = new Jackson2JsonEncoder(); this.configurer.defaultCodec().jackson2Encoder(encoder); - assertSame(encoder, this.configurer.getWriters().stream() - .filter(writer -> writer instanceof EncoderHttpMessageWriter) - .map(writer -> ((EncoderHttpMessageWriter) writer).getEncoder()) - .filter(e -> Jackson2JsonEncoder.class.equals(e.getClass())) - .findFirst() - .filter(e -> e == encoder).orElse(null)); - assertSame(encoder, this.configurer.getWriters().stream() .filter(writer -> ServerSentEventHttpMessageWriter.class.equals(writer.getClass())) .map(writer -> (ServerSentEventHttpMessageWriter) writer) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java index c8f6ed9a7c2..cee40b2c91a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java @@ -71,16 +71,6 @@ import org.springframework.web.server.handler.ResponseStatusExceptionHandler; */ public class WebFluxConfigurationSupport implements ApplicationContextAware { - private static final boolean jackson2Present = - ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", - WebFluxConfigurationSupport.class.getClassLoader()) && - ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", - WebFluxConfigurationSupport.class.getClassLoader()); - - private static final boolean jaxb2Present = - ClassUtils.isPresent("javax.xml.bind.Binder", WebFluxConfigurationSupport.class.getClassLoader()); - - private Map corsConfigurations; private PathMatchConfigurer pathMatchConfigurer; @@ -159,7 +149,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { */ protected Map getDefaultMediaTypeMappings() { Map map = new HashMap<>(); - if (jackson2Present) { + if (ServerCodecConfigurer.jackson2Present) { map.put("json", MediaType.APPLICATION_JSON); } return map;