提交 dc3851df 编写于 作者: R Rossen Stoyanchev

Extract AbstractCodecConfigurer base class

Issue: SPR-15247
上级 5211a099
/*
* 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.
* <p>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<HttpMessageReader<?>> getReaders() {
List<HttpMessageReader<?>> 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<HttpMessageReader<?>> 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<HttpMessageReader<?>> result) {
customCodec().addTypedReadersTo(result);
}
/**
* Add built-in, Object-based readers.
*/
protected void addDefaultObjectReaders(List<HttpMessageReader<?>> 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<HttpMessageReader<?>> result) {
customCodec().addObjectReadersTo(result);
}
/**
* Prepare a list of HTTP message writers.
*/
public List<HttpMessageWriter<?>> getWriters() {
List<HttpMessageWriter<?>> 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<HttpMessageWriter<?>> 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<HttpMessageWriter<?>> result) {
customCodec().addTypedWritersTo(result);
}
/**
* Add built-in, Object-based readers.
*/
protected void addDefaultObjectWriters(List<HttpMessageWriter<?>> 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<HttpMessageWriter<?>> 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<Class<?>, HttpMessageReader<?>> readers = new HashMap<>();
private final Map<Class<?>, 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<Class<?>, HttpMessageReader<?>> getReaders() {
return this.readers;
}
protected Map<Class<?>, 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 <T, D extends Decoder<T>> void addReaderTo(List<HttpMessageReader<?>> result,
Class<D> key, Supplier<D> fallback) {
addReaderTo(result, () -> findDecoderReader(key, fallback));
}
protected void addReaderTo(List<HttpMessageReader<?>> result,
Supplier<HttpMessageReader<?>> reader) {
if (!this.suppressed) {
result.add(reader.get());
}
}
protected <T, D extends Decoder<T>> DecoderHttpMessageReader<?> findDecoderReader(
Class<D> decoderType, Supplier<D> fallback) {
DecoderHttpMessageReader<?> reader = (DecoderHttpMessageReader<?>) this.readers.get(decoderType);
return reader != null ? reader : new DecoderHttpMessageReader<>(fallback.get());
}
@SuppressWarnings("unchecked")
protected HttpMessageReader<?> findReader(Class<?> key, Supplier<HttpMessageReader<?>> fallback) {
return this.readers.containsKey(key) ? this.readers.get(key) : fallback.get();
}
protected <T, E extends Encoder<T>> void addWriterTo(List<HttpMessageWriter<?>> result,
Class<E> key, Supplier<E> fallback) {
addWriterTo(result, () -> findEncoderWriter(key, fallback));
}
protected void addWriterTo(List<HttpMessageWriter<?>> result,
Supplier<HttpMessageWriter<?>> writer) {
if (!this.suppressed) {
result.add(writer.get());
}
}
protected <T, E extends Encoder<T>> EncoderHttpMessageWriter<?> findEncoderWriter(
Class<E> encoderType, Supplier<E> fallback) {
EncoderHttpMessageWriter<?> writer = (EncoderHttpMessageWriter<?>) this.writers.get(encoderType);
return writer != null ? writer : new EncoderHttpMessageWriter<>(fallback.get());
}
@SuppressWarnings("unchecked")
protected HttpMessageWriter<?> findWriter(Class<?> key, Supplier<HttpMessageWriter<?>> fallback) {
return this.writers.containsKey(key) ? this.writers.get(key) : fallback.get();
}
protected void addStringReaderTextOnlyTo(List<HttpMessageReader<?>> result) {
addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly(true)));
}
protected void addStringReaderTo(List<HttpMessageReader<?>> result) {
addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
}
protected void addStringWriterTextPlainOnlyTo(List<HttpMessageWriter<?>> result) {
addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
}
protected void addStringWriterTo(List<HttpMessageWriter<?>> result) {
addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()));
}
}
/**
* Registry and container for custom HTTP message readers and writers.
*/
public static class CustomCodecConfigurer {
private final List<HttpMessageReader<?>> typedReaders = new ArrayList<>();
private final List<HttpMessageWriter<?>> typedWriters = new ArrayList<>();
private final List<HttpMessageReader<?>> objectReaders = new ArrayList<>();
private final List<HttpMessageWriter<?>> 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<HttpMessageReader<?>> result) {
result.addAll(this.typedReaders);
}
protected void addObjectReadersTo(List<HttpMessageReader<?>> result) {
result.addAll(this.objectReaders);
}
protected void addTypedWritersTo(List<HttpMessageWriter<?>> result) {
result.addAll(this.typedWriters);
}
protected void addObjectWritersTo(List<HttpMessageWriter<?>> result) {
result.addAll(this.objectWriters);
}
}
}
......@@ -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()}.
*
* <p>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
* <p>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.
* <p>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<HttpMessageReader<?>> getReaders() {
// Built-in, concrete Java type readers
List<HttpMessageReader<?>> 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<HttpMessageReader<?>> result) {
super.addDefaultTypedReaders(result);
defaultCodec().addReaderTo(result, FormHttpMessageReader::new);
}
/**
* Prepare a list of HTTP message writers.
*/
public List<HttpMessageWriter<?>> getWriters() {
// Built-in, concrete Java type readers
List<HttpMessageWriter<?>> 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<HttpMessageWriter<?>> 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<Class<?>, HttpMessageReader<?>> readers = new HashMap<>();
private final Map<Class<?>, 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.
* <p>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 <T, D extends Decoder<T>> void addReaderTo(List<HttpMessageReader<?>> result,
Class<D> key, Supplier<D> fallback) {
addReaderTo(result, () -> findReader(key, fallback));
}
private void addReaderTo(List<HttpMessageReader<?>> result,
Supplier<HttpMessageReader<?>> reader) {
if (!this.suppressed) {
result.add(reader.get());
}
}
private <T, D extends Decoder<T>> DecoderHttpMessageReader<?> findReader(
Class<D> key, Supplier<D> fallback) {
DecoderHttpMessageReader<?> reader = (DecoderHttpMessageReader<?>) this.readers.get(key);
return reader != null ? reader : new DecoderHttpMessageReader<>(fallback.get());
}
private <T, E extends Encoder<T>> void addWriterTo(List<HttpMessageWriter<?>> result,
Class<E> key, Supplier<E> fallback) {
addWriterTo(result, () -> findWriter(key, fallback));
}
private void addWriterTo(List<HttpMessageWriter<?>> result,
Supplier<HttpMessageWriter<?>> writer) {
if (!this.suppressed) {
result.add(writer.get());
}
}
private <T, E extends Encoder<T>> EncoderHttpMessageWriter<?> findWriter(
Class<E> key, Supplier<E> fallback) {
EncoderHttpMessageWriter<?> writer = (EncoderHttpMessageWriter<?>) this.writers.get(key);
return writer != null ? writer : new EncoderHttpMessageWriter<>(fallback.get());
}
private void addStringReaderTextOnlyTo(List<HttpMessageReader<?>> result) {
addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly(true)));
}
private void addStringReaderTo(List<HttpMessageReader<?>> result) {
addReaderTo(result, () -> new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes(true)));
}
private void addStringWriterTextPlainOnlyTo(List<HttpMessageWriter<?>> result) {
addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
}
private void addStringWriterTo(List<HttpMessageWriter<?>> result) {
addWriterTo(result, () -> new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()));
}
private void addSseWriterTo(List<HttpMessageWriter<?>> result) {
addWriterTo(result, () -> {
HttpMessageWriter<?> writer = this.writers.get(ServerSentEventHttpMessageWriter.class);
if (writer != null) {
return writer;
}
private void addServerSentEventWriterTo(List<HttpMessageWriter<?>> 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<HttpMessageReader<?>> typedReaders = new ArrayList<>();
private final List<HttpMessageWriter<?>> typedWriters = new ArrayList<>();
private final List<HttpMessageReader<?>> objectReaders = new ArrayList<>();
private final List<HttpMessageWriter<?>> 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<HttpMessageReader<?>> result) {
result.addAll(this.typedReaders);
}
private void addObjectReadersTo(List<HttpMessageReader<?>> result) {
result.addAll(this.objectReaders);
}
private void addTypedWritersTo(List<HttpMessageWriter<?>> result) {
result.addAll(this.typedWriters);
}
private void addObjectWritersTo(List<HttpMessageWriter<?>> result) {
result.addAll(this.objectWriters);
return new ServerSentEventHttpMessageWriter(encoder);
}));
}
}
......
/*
* 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<HttpMessageReader<?>> 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<HttpMessageWriter<?>> 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<HttpMessageReader<?>> 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<HttpMessageWriter<?>> 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<HttpMessageReader<?>> 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<HttpMessageWriter<?>> 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<HttpMessageReader<?>> readers) {
HttpMessageReader<?> reader = readers.get(this.index.getAndIncrement());
assertEquals(DecoderHttpMessageReader.class, reader.getClass());
return ((DecoderHttpMessageReader) reader).getDecoder();
}
private Encoder<?> getNextEncoder(List<HttpMessageWriter<?>> 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());
}
}
}
......@@ -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<HttpMessageReader<?>> 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<HttpMessageWriter<?>> 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<HttpMessageReader<?>> 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<HttpMessageWriter<?>> 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)
......
......@@ -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<String, CorsConfiguration> corsConfigurations;
private PathMatchConfigurer pathMatchConfigurer;
......@@ -159,7 +149,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
*/
protected Map<String, MediaType> getDefaultMediaTypeMappings() {
Map<String, MediaType> map = new HashMap<>();
if (jackson2Present) {
if (ServerCodecConfigurer.jackson2Present) {
map.put("json", MediaType.APPLICATION_JSON);
}
return map;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册