Polish CodecConfigurer related classes
Functionally equivalent updates to package private classes to improve the code and make it easier to understand.
This commit is contained in:
@@ -20,27 +20,25 @@ import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
|
||||
/**
|
||||
* Helps to configure a list of client-side HTTP message readers and writers
|
||||
* with support for built-in defaults and options to register additional custom
|
||||
* readers and writers via {@link #customCodecs()}.
|
||||
*
|
||||
* <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 #defaultCodecs() override} some of the defaults or to have them
|
||||
* {@link #registerDefaults(boolean) turned off} completely.
|
||||
* Extension of {@link CodecConfigurer} for HTTP message reader and writer
|
||||
* options relevant on the client side.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public interface ClientCodecConfigurer extends CodecConfigurer {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>On the client side, built-in default also include customizations related
|
||||
* to multipart readers and writers, as well as the decoder for SSE.
|
||||
*/
|
||||
@Override
|
||||
ClientDefaultCodecs defaultCodecs();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code ClientCodecConfigurer}.
|
||||
* Static factory method for a {@code ClientCodecConfigurer}.
|
||||
*/
|
||||
static ClientCodecConfigurer create() {
|
||||
return CodecConfigurerFactory.create(ClientCodecConfigurer.class);
|
||||
@@ -48,7 +46,7 @@ public interface ClientCodecConfigurer extends CodecConfigurer {
|
||||
|
||||
|
||||
/**
|
||||
* Extension of {@link CodecConfigurer.DefaultCodecs} with extra client options.
|
||||
* {@link CodecConfigurer.DefaultCodecs} extension with extra client-side options.
|
||||
*/
|
||||
interface ClientDefaultCodecs extends DefaultCodecs {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -23,9 +23,30 @@ import org.springframework.core.codec.Encoder;
|
||||
|
||||
/**
|
||||
* Defines a common interface for configuring either client or server HTTP
|
||||
* message readers and writers. To obtain an instance use either
|
||||
* {@link ClientCodecConfigurer#create()} or
|
||||
* {@link ServerCodecConfigurer#create()}.
|
||||
* message readers and writers. This is used as follows:
|
||||
* <ul>
|
||||
* <li>Use {@link ClientCodecConfigurer#create()} or
|
||||
* {@link ServerCodecConfigurer#create()} to create an instance.
|
||||
* <li>Use {@link #defaultCodecs()} to customize HTTP message readers or writers
|
||||
* registered by default.
|
||||
* <li>Use {@link #customCodecs()} to add custom HTTP message readers or writers.
|
||||
* <li>Use {@link #getReaders()} and {@link #getWriters()} to obtain the list of
|
||||
* configured HTTP message readers and writers.
|
||||
* </ul>
|
||||
*
|
||||
* <p>HTTP message readers and writers are divided into 3 categories that are
|
||||
* ordered as follows:
|
||||
* <ol>
|
||||
* <li>Typed readers and writers that support specific types, e.g. byte[], String.
|
||||
* <li>Object readers and writers, e.g. JSON, XML.
|
||||
* <li>Catch-all readers or writers, e.g. String with any media type.
|
||||
* </ol>
|
||||
*
|
||||
* <p>Typed and object readers are further sub-divided and ordered as follows:
|
||||
* <ol>
|
||||
* <li>Default HTTP reader and writer registrations.
|
||||
* <li>Custom readers and writers.
|
||||
* </ol>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
@@ -33,22 +54,28 @@ import org.springframework.core.codec.Encoder;
|
||||
public interface CodecConfigurer {
|
||||
|
||||
/**
|
||||
* Configure or customize the default HTTP message readers and writers.
|
||||
* Provides a way to customize or replace HTTP message readers and writers
|
||||
* registered by default.
|
||||
* @see #registerDefaults(boolean)
|
||||
*/
|
||||
DefaultCodecs defaultCodecs();
|
||||
|
||||
/**
|
||||
* Whether to register default HTTP message readers and writers.
|
||||
* <p>By default this is set to {@code "true"}; setting this to {@code false}
|
||||
* disables default HTTP message reader and writer registrations.
|
||||
* Register custom HTTP message readers or writers in addition to the ones
|
||||
* registered by default.
|
||||
*/
|
||||
CustomCodecs customCodecs();
|
||||
|
||||
/**
|
||||
* Provides a way to completely turn off registration of default HTTP message
|
||||
* readers and writers, and instead rely only on the ones provided via
|
||||
* {@link #customCodecs()}.
|
||||
* <p>By default this is set to {@code "true"} in which case default
|
||||
* registrations are made; setting this to {@code false} disables default
|
||||
* registrations.
|
||||
*/
|
||||
void registerDefaults(boolean registerDefaults);
|
||||
|
||||
/**
|
||||
* Register custom HTTP message readers or writers to use in addition to
|
||||
* the ones registered by default.
|
||||
*/
|
||||
CustomCodecs customCodecs();
|
||||
|
||||
/**
|
||||
* Obtain the configured HTTP message readers.
|
||||
@@ -62,9 +89,10 @@ public interface CodecConfigurer {
|
||||
|
||||
|
||||
/**
|
||||
* Assists with customizing the default HTTP message readers and writers.
|
||||
* @see ClientCodecConfigurer.ClientDefaultCodecs
|
||||
* @see ServerCodecConfigurer.ServerDefaultCodecs
|
||||
* Customize or replace the HTTP message readers and writers registered by
|
||||
* default. The options are further extended by
|
||||
* {@link ClientCodecConfigurer.ClientDefaultCodecs ClientDefaultCodecs} and
|
||||
* {@link ServerCodecConfigurer.ServerDefaultCodecs ServerDefaultCodecs}.
|
||||
*/
|
||||
interface DefaultCodecs {
|
||||
|
||||
@@ -85,7 +113,7 @@ public interface CodecConfigurer {
|
||||
|
||||
|
||||
/**
|
||||
* Registry and container for custom HTTP message readers and writers.
|
||||
* Registry for custom HTTP message readers and writers.
|
||||
*/
|
||||
interface CustomCodecs {
|
||||
|
||||
|
||||
@@ -19,27 +19,25 @@ package org.springframework.http.codec;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
|
||||
/**
|
||||
* 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 #customCodecs()}.
|
||||
*
|
||||
* <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 #defaultCodecs() override} some of the defaults or to have them
|
||||
* {@link #registerDefaults(boolean) turned off} completely.
|
||||
* Extension of {@link CodecConfigurer} for HTTP message reader and writer
|
||||
* options relevant on the server side.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public interface ServerCodecConfigurer extends CodecConfigurer {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>On the server side, built-in default also include customizations
|
||||
* related to the encoder for SSE.
|
||||
*/
|
||||
@Override
|
||||
ServerDefaultCodecs defaultCodecs();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code ServerCodecConfigurer}.
|
||||
* Static factory method for a {@code ServerCodecConfigurer}.
|
||||
*/
|
||||
static ServerCodecConfigurer create() {
|
||||
return CodecConfigurerFactory.create(ServerCodecConfigurer.class);
|
||||
@@ -47,7 +45,7 @@ public interface ServerCodecConfigurer extends CodecConfigurer {
|
||||
|
||||
|
||||
/**
|
||||
* Extension of {@link CodecConfigurer.DefaultCodecs} with extra server options.
|
||||
* {@link CodecConfigurer.DefaultCodecs} extension with extra client-side options.
|
||||
*/
|
||||
interface ServerDefaultCodecs extends DefaultCodecs {
|
||||
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
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.CodecConfigurer;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link CodecConfigurer}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
abstract class AbstractCodecConfigurer implements CodecConfigurer {
|
||||
|
||||
static final boolean jackson2Present =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
||||
AbstractCodecConfigurer.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
|
||||
AbstractCodecConfigurer.class.getClassLoader());
|
||||
|
||||
private static final boolean jackson2SmilePresent =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory",
|
||||
AbstractCodecConfigurer.class.getClassLoader());
|
||||
|
||||
private static final boolean jaxb2Present =
|
||||
ClassUtils.isPresent("javax.xml.bind.Binder", AbstractCodecConfigurer.class.getClassLoader());
|
||||
|
||||
|
||||
private final AbstractDefaultCodecs defaultCodecs;
|
||||
|
||||
private final DefaultCustomCodecs customCodecs = new DefaultCustomCodecs();
|
||||
|
||||
|
||||
AbstractCodecConfigurer(AbstractDefaultCodecs defaultCodecs) {
|
||||
Assert.notNull(defaultCodecs, "'defaultCodecs' is required");
|
||||
this.defaultCodecs = defaultCodecs;
|
||||
this.defaultCodecs.setCustomCodecs(this.customCodecs);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultCodecs defaultCodecs() {
|
||||
return this.defaultCodecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDefaults(boolean shouldRegister) {
|
||||
this.defaultCodecs.registerDefaults(shouldRegister);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomCodecs customCodecs() {
|
||||
return this.customCodecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpMessageReader<?>> getReaders() {
|
||||
List<HttpMessageReader<?>> result = new ArrayList<>();
|
||||
|
||||
result.addAll(this.defaultCodecs.getTypedReaders());
|
||||
result.addAll(this.customCodecs.getTypedReaders());
|
||||
|
||||
result.addAll(this.defaultCodecs.getObjectReaders());
|
||||
result.addAll(this.customCodecs.getObjectReaders());
|
||||
|
||||
result.addAll(this.defaultCodecs.getCatchAllReaders());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpMessageWriter<?>> getWriters() {
|
||||
List<HttpMessageWriter<?>> result = new ArrayList<>();
|
||||
|
||||
result.addAll(this.defaultCodecs.getTypedWriters());
|
||||
result.addAll(this.customCodecs.getTypedWriters());
|
||||
|
||||
result.addAll(this.defaultCodecs.getObjectWriters());
|
||||
result.addAll(this.customCodecs.getObjectWriters());
|
||||
|
||||
result.addAll(this.defaultCodecs.getCatchAllWriters());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
abstract static class AbstractDefaultCodecs implements DefaultCodecs {
|
||||
|
||||
private boolean registerDefaults = true;
|
||||
|
||||
@Nullable
|
||||
private Decoder<?> jackson2JsonDecoder;
|
||||
|
||||
@Nullable
|
||||
private Encoder<?> jackson2JsonEncoder;
|
||||
|
||||
@Nullable
|
||||
private DefaultCustomCodecs customCodecs;
|
||||
|
||||
void registerDefaults(boolean registerDefaults) {
|
||||
this.registerDefaults = registerDefaults;
|
||||
}
|
||||
|
||||
boolean shouldRegisterDefaults() {
|
||||
return this.registerDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access to custom codecs for subclasses, e.g. for multipart writers.
|
||||
*/
|
||||
void setCustomCodecs(@Nullable DefaultCustomCodecs customCodecs) {
|
||||
this.customCodecs = customCodecs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
DefaultCustomCodecs getCustomCodecs() {
|
||||
return this.customCodecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jackson2JsonDecoder(Decoder<?> decoder) {
|
||||
this.jackson2JsonDecoder = decoder;
|
||||
}
|
||||
|
||||
Decoder<?> getJackson2JsonDecoder() {
|
||||
return (this.jackson2JsonDecoder != null ? this.jackson2JsonDecoder : new Jackson2JsonDecoder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jackson2JsonEncoder(Encoder<?> encoder) {
|
||||
this.jackson2JsonEncoder = encoder;
|
||||
}
|
||||
|
||||
Encoder<?> getJackson2JsonEncoder() {
|
||||
return (this.jackson2JsonEncoder != null ? this.jackson2JsonEncoder : new Jackson2JsonEncoder());
|
||||
}
|
||||
|
||||
// Readers...
|
||||
|
||||
List<HttpMessageReader<?>> getTypedReaders() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> result = new ArrayList<>();
|
||||
result.add(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
|
||||
result.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
result.add(new DecoderHttpMessageReader<>(new DataBufferDecoder()));
|
||||
result.add(new DecoderHttpMessageReader<>(new ResourceDecoder()));
|
||||
result.add(new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly()));
|
||||
return result;
|
||||
}
|
||||
|
||||
List<HttpMessageReader<?>> getObjectReaders() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> result = new ArrayList<>();
|
||||
if (jackson2Present) {
|
||||
result.add(new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
|
||||
}
|
||||
if (jackson2SmilePresent) {
|
||||
result.add(new DecoderHttpMessageReader<>(new Jackson2SmileDecoder()));
|
||||
}
|
||||
if (jaxb2Present) {
|
||||
result.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
List<HttpMessageReader<?>> getCatchAllReaders() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> result = new ArrayList<>();
|
||||
result.add(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes()));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Writers...
|
||||
|
||||
List<HttpMessageWriter<?>> getTypedWriters() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> result = new ArrayList<>();
|
||||
result.add(new EncoderHttpMessageWriter<>(new ByteArrayEncoder()));
|
||||
result.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
result.add(new EncoderHttpMessageWriter<>(new DataBufferEncoder()));
|
||||
result.add(new ResourceHttpMessageWriter());
|
||||
result.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
|
||||
return result;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getObjectWriters() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> result = new ArrayList<>();
|
||||
if (jackson2Present) {
|
||||
result.add(new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
|
||||
}
|
||||
if (jackson2SmilePresent) {
|
||||
result.add(new EncoderHttpMessageWriter<>(new Jackson2SmileEncoder()));
|
||||
}
|
||||
if (jaxb2Present) {
|
||||
result.add(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getCatchAllWriters() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> result = new ArrayList<>();
|
||||
result.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class DefaultCustomCodecs implements CustomCodecs {
|
||||
|
||||
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<>();
|
||||
|
||||
@Override
|
||||
public void decoder(Decoder<?> decoder) {
|
||||
reader(new DecoderHttpMessageReader<>(decoder));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encoder(Encoder<?> encoder) {
|
||||
writer(new EncoderHttpMessageWriter<>(encoder));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reader(HttpMessageReader<?> reader) {
|
||||
boolean canReadToObject = reader.canRead(ResolvableType.forClass(Object.class), null);
|
||||
(canReadToObject ? this.objectReaders : this.typedReaders).add(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writer(HttpMessageWriter<?> writer) {
|
||||
boolean canWriteObject = writer.canWrite(ResolvableType.forClass(Object.class), null);
|
||||
(canWriteObject ? this.objectWriters : this.typedWriters).add(writer);
|
||||
}
|
||||
|
||||
List<HttpMessageReader<?>> getTypedReaders() {
|
||||
return this.typedReaders;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getTypedWriters() {
|
||||
return this.typedWriters;
|
||||
}
|
||||
|
||||
List<HttpMessageReader<?>> getObjectReaders() {
|
||||
return this.objectReaders;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getObjectWriters() {
|
||||
return this.objectWriters;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link CodecConfigurer} that serves as a base for
|
||||
* client and server specific variants.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
class BaseCodecConfigurer implements CodecConfigurer {
|
||||
|
||||
private final BaseDefaultCodecs defaultCodecs;
|
||||
|
||||
private final DefaultCustomCodecs customCodecs = new DefaultCustomCodecs();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor with the base {@link BaseDefaultCodecs} to use, which can be
|
||||
* a client or server specific variant.
|
||||
*/
|
||||
BaseCodecConfigurer(BaseDefaultCodecs defaultCodecs) {
|
||||
Assert.notNull(defaultCodecs, "'defaultCodecs' is required");
|
||||
this.defaultCodecs = defaultCodecs;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DefaultCodecs defaultCodecs() {
|
||||
return this.defaultCodecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDefaults(boolean shouldRegister) {
|
||||
this.defaultCodecs.registerDefaults(shouldRegister);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomCodecs customCodecs() {
|
||||
return this.customCodecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpMessageReader<?>> getReaders() {
|
||||
List<HttpMessageReader<?>> result = new ArrayList<>();
|
||||
|
||||
result.addAll(this.defaultCodecs.getTypedReaders());
|
||||
result.addAll(this.customCodecs.getTypedReaders());
|
||||
|
||||
result.addAll(this.defaultCodecs.getObjectReaders());
|
||||
result.addAll(this.customCodecs.getObjectReaders());
|
||||
|
||||
result.addAll(this.defaultCodecs.getCatchAllReaders());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpMessageWriter<?>> getWriters() {
|
||||
List<HttpMessageWriter<?>> result = new ArrayList<>();
|
||||
|
||||
result.addAll(this.defaultCodecs.getTypedWriters());
|
||||
result.addAll(this.customCodecs.getTypedWriters());
|
||||
|
||||
result.addAll(this.defaultCodecs.getObjectWriters());
|
||||
result.addAll(this.customCodecs.getObjectWriters());
|
||||
|
||||
result.addAll(this.defaultCodecs.getCatchAllWriters());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Accessors for use in sub-classes...
|
||||
|
||||
protected Supplier<List<HttpMessageWriter<?>>> getCustomTypedWriters() {
|
||||
return () -> this.customCodecs.typedWriters;
|
||||
}
|
||||
|
||||
protected Supplier<List<HttpMessageWriter<?>>> getCustomObjectWriters() {
|
||||
return () -> this.customCodecs.objectWriters;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of {@code CustomCodecs}.
|
||||
*/
|
||||
private static final class DefaultCustomCodecs implements CustomCodecs {
|
||||
|
||||
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<>();
|
||||
|
||||
|
||||
@Override
|
||||
public void decoder(Decoder<?> decoder) {
|
||||
reader(new DecoderHttpMessageReader<>(decoder));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encoder(Encoder<?> encoder) {
|
||||
writer(new EncoderHttpMessageWriter<>(encoder));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reader(HttpMessageReader<?> reader) {
|
||||
boolean canReadToObject = reader.canRead(ResolvableType.forClass(Object.class), null);
|
||||
(canReadToObject ? this.objectReaders : this.typedReaders).add(reader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writer(HttpMessageWriter<?> writer) {
|
||||
boolean canWriteObject = writer.canWrite(ResolvableType.forClass(Object.class), null);
|
||||
(canWriteObject ? this.objectWriters : this.typedWriters).add(writer);
|
||||
}
|
||||
|
||||
|
||||
// Package private accessors...
|
||||
|
||||
List<HttpMessageReader<?>> getTypedReaders() {
|
||||
return this.typedReaders;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getTypedWriters() {
|
||||
return this.typedWriters;
|
||||
}
|
||||
|
||||
List<HttpMessageReader<?>> getObjectReaders() {
|
||||
return this.objectReaders;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getObjectWriters() {
|
||||
return this.objectWriters;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
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.CodecConfigurer;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.FormHttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2SmileEncoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
|
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link CodecConfigurer.DefaultCodecs} that serves
|
||||
* as a base for client and server specific variants.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs {
|
||||
|
||||
static final boolean jackson2Present =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
||||
BaseCodecConfigurer.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
|
||||
BaseCodecConfigurer.class.getClassLoader());
|
||||
|
||||
private static final boolean jackson2SmilePresent =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory",
|
||||
BaseCodecConfigurer.class.getClassLoader());
|
||||
|
||||
private static final boolean jaxb2Present =
|
||||
ClassUtils.isPresent("javax.xml.bind.Binder", BaseCodecConfigurer.class.getClassLoader());
|
||||
|
||||
|
||||
@Nullable
|
||||
private Decoder<?> jackson2JsonDecoder;
|
||||
|
||||
@Nullable
|
||||
private Encoder<?> jackson2JsonEncoder;
|
||||
|
||||
private boolean registerDefaults = true;
|
||||
|
||||
|
||||
@Override
|
||||
public void jackson2JsonDecoder(Decoder<?> decoder) {
|
||||
this.jackson2JsonDecoder = decoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jackson2JsonEncoder(Encoder<?> encoder) {
|
||||
this.jackson2JsonEncoder = encoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate method used from {@link BaseCodecConfigurer#registerDefaults}.
|
||||
*/
|
||||
void registerDefaults(boolean registerDefaults) {
|
||||
this.registerDefaults = registerDefaults;
|
||||
}
|
||||
|
||||
|
||||
// Package private access to the configured readers...
|
||||
|
||||
final List<HttpMessageReader<?>> getTypedReaders() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||
readers.add(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new DataBufferDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(new ResourceDecoder()));
|
||||
readers.add(new DecoderHttpMessageReader<>(StringDecoder.textPlainOnly()));
|
||||
readers.add(new FormHttpMessageReader());
|
||||
extendTypedReaders(readers);
|
||||
return readers;
|
||||
}
|
||||
|
||||
protected void extendTypedReaders(List<HttpMessageReader<?>> typedReaders) {
|
||||
}
|
||||
|
||||
final List<HttpMessageReader<?>> getObjectReaders() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> readers = new ArrayList<>();
|
||||
if (jackson2Present) {
|
||||
readers.add(new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
|
||||
}
|
||||
if (jackson2SmilePresent) {
|
||||
readers.add(new DecoderHttpMessageReader<>(new Jackson2SmileDecoder()));
|
||||
}
|
||||
if (jaxb2Present) {
|
||||
readers.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
|
||||
}
|
||||
extendObjectReaders(readers);
|
||||
return readers;
|
||||
}
|
||||
|
||||
protected void extendObjectReaders(List<HttpMessageReader<?>> objectReaders) {
|
||||
}
|
||||
|
||||
final List<HttpMessageReader<?>> getCatchAllReaders() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> result = new ArrayList<>();
|
||||
result.add(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Package private access to the configured writers...
|
||||
|
||||
final List<HttpMessageWriter<?>> getTypedWriters() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> writers = new ArrayList<>();
|
||||
writers.add(new EncoderHttpMessageWriter<>(new ByteArrayEncoder()));
|
||||
writers.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
|
||||
writers.add(new EncoderHttpMessageWriter<>(new DataBufferEncoder()));
|
||||
writers.add(new ResourceHttpMessageWriter());
|
||||
writers.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.textPlainOnly()));
|
||||
extendTypedWriters(writers);
|
||||
return writers;
|
||||
}
|
||||
|
||||
protected void extendTypedWriters(List<HttpMessageWriter<?>> typedWriters) {
|
||||
}
|
||||
|
||||
final List<HttpMessageWriter<?>> getObjectWriters() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> writers = new ArrayList<>();
|
||||
if (jackson2Present) {
|
||||
writers.add(new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
|
||||
}
|
||||
if (jackson2SmilePresent) {
|
||||
writers.add(new EncoderHttpMessageWriter<>(new Jackson2SmileEncoder()));
|
||||
}
|
||||
if (jaxb2Present) {
|
||||
writers.add(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
|
||||
}
|
||||
extendObjectWriters(writers);
|
||||
return writers;
|
||||
}
|
||||
|
||||
protected void extendObjectWriters(List<HttpMessageWriter<?>> objectWriters) {
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getCatchAllWriters() {
|
||||
if (!this.registerDefaults) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> result = new ArrayList<>();
|
||||
result.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Accessors for use in sub-classes...
|
||||
|
||||
protected Decoder<?> getJackson2JsonDecoder() {
|
||||
return (this.jackson2JsonDecoder != null ? this.jackson2JsonDecoder : new Jackson2JsonDecoder());
|
||||
}
|
||||
|
||||
protected Encoder<?> getJackson2JsonEncoder() {
|
||||
return (this.jackson2JsonEncoder != null ? this.jackson2JsonEncoder : new Jackson2JsonEncoder());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.http.codec.ClientCodecConfigurer;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.FormHttpMessageWriter;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerSentEventHttpMessageReader;
|
||||
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ClientCodecConfigurer.ClientDefaultCodecs}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
class ClientDefaultCodecsImpl extends BaseDefaultCodecs implements ClientCodecConfigurer.ClientDefaultCodecs {
|
||||
|
||||
@Nullable
|
||||
private DefaultMultipartCodecs multipartCodecs;
|
||||
|
||||
@Nullable
|
||||
private Decoder<?> sseDecoder;
|
||||
|
||||
@Nullable
|
||||
private Supplier<List<HttpMessageWriter<?>>> customTypedWriters;
|
||||
|
||||
@Nullable
|
||||
private Supplier<List<HttpMessageWriter<?>>> customObjectWriters;
|
||||
|
||||
|
||||
void initCustomTypedWriters(Supplier<List<HttpMessageWriter<?>>> supplier) {
|
||||
this.customTypedWriters = supplier;
|
||||
}
|
||||
|
||||
void initCustomObjectWriters(Supplier<List<HttpMessageWriter<?>>> supplier) {
|
||||
this.customObjectWriters = supplier;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientCodecConfigurer.MultipartCodecs multipartCodecs() {
|
||||
if (this.multipartCodecs == null) {
|
||||
this.multipartCodecs = new DefaultMultipartCodecs();
|
||||
}
|
||||
return this.multipartCodecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverSentEventDecoder(Decoder<?> decoder) {
|
||||
this.sseDecoder = decoder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void extendObjectReaders(List<HttpMessageReader<?>> objectReaders) {
|
||||
objectReaders.add(new ServerSentEventHttpMessageReader(getSseDecoder()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Decoder<?> getSseDecoder() {
|
||||
return this.sseDecoder != null ? this.sseDecoder : jackson2Present ? getJackson2JsonDecoder() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendTypedWriters(List<HttpMessageWriter<?>> typedWriters) {
|
||||
|
||||
MultipartHttpMessageWriter multipartWriter = new MultipartHttpMessageWriter(
|
||||
resolvePartWriters(typedWriters, getObjectWriters()), new FormHttpMessageWriter());
|
||||
|
||||
typedWriters.add(multipartWriter);
|
||||
}
|
||||
|
||||
private List<HttpMessageWriter<?>> resolvePartWriters(List<HttpMessageWriter<?>> typedWriters,
|
||||
List<HttpMessageWriter<?>> objectWriters) {
|
||||
|
||||
List<HttpMessageWriter<?>> partWriters;
|
||||
if (this.multipartCodecs != null) {
|
||||
partWriters = this.multipartCodecs.getWriters();
|
||||
}
|
||||
else {
|
||||
Assert.notNull(this.customTypedWriters, "Expected custom typed writers supplier.");
|
||||
Assert.notNull(this.customObjectWriters, "Expected custom object writers supplier.");
|
||||
|
||||
partWriters = new ArrayList<>(typedWriters);
|
||||
partWriters.addAll(this.customTypedWriters.get());
|
||||
|
||||
partWriters.addAll(objectWriters);
|
||||
partWriters.addAll(this.customObjectWriters.get());
|
||||
|
||||
partWriters.addAll(super.getCatchAllWriters());
|
||||
}
|
||||
return partWriters;
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultMultipartCodecs implements ClientCodecConfigurer.MultipartCodecs {
|
||||
|
||||
private final List<HttpMessageWriter<?>> writers = new ArrayList<>();
|
||||
|
||||
|
||||
@Override
|
||||
public ClientCodecConfigurer.MultipartCodecs encoder(Encoder<?> encoder) {
|
||||
writer(new EncoderHttpMessageWriter<>(encoder));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientCodecConfigurer.MultipartCodecs writer(HttpMessageWriter<?> writer) {
|
||||
this.writers.add(writer);
|
||||
return this;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getWriters() {
|
||||
return this.writers;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,20 +16,7 @@
|
||||
|
||||
package org.springframework.http.codec.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.http.codec.ClientCodecConfigurer;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.FormHttpMessageWriter;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerSentEventHttpMessageReader;
|
||||
import org.springframework.http.codec.multipart.MultipartHttpMessageWriter;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ClientCodecConfigurer}.
|
||||
@@ -37,108 +24,19 @@ import org.springframework.lang.Nullable;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements ClientCodecConfigurer {
|
||||
public class DefaultClientCodecConfigurer extends BaseCodecConfigurer implements ClientCodecConfigurer {
|
||||
|
||||
|
||||
public DefaultClientCodecConfigurer() {
|
||||
super(new ClientDefaultCodecsImpl());
|
||||
((ClientDefaultCodecsImpl) defaultCodecs()).initCustomTypedWriters(getCustomTypedWriters());
|
||||
((ClientDefaultCodecsImpl) defaultCodecs()).initCustomObjectWriters(getCustomObjectWriters());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientDefaultCodecs defaultCodecs() {
|
||||
return (ClientDefaultCodecs) super.defaultCodecs();
|
||||
}
|
||||
|
||||
|
||||
private static class ClientDefaultCodecsImpl extends AbstractDefaultCodecs implements ClientDefaultCodecs {
|
||||
|
||||
@Nullable
|
||||
private DefaultMultipartCodecs multipartCodecs;
|
||||
|
||||
@Nullable
|
||||
private Decoder<?> sseDecoder;
|
||||
|
||||
@Override
|
||||
public MultipartCodecs multipartCodecs() {
|
||||
if (this.multipartCodecs == null) {
|
||||
this.multipartCodecs = new DefaultMultipartCodecs();
|
||||
}
|
||||
return this.multipartCodecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverSentEventDecoder(Decoder<?> decoder) {
|
||||
this.sseDecoder = decoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<HttpMessageReader<?>> getObjectReaders() {
|
||||
if (!shouldRegisterDefaults()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> result = super.getObjectReaders();
|
||||
result.add(new ServerSentEventHttpMessageReader(getSseDecoder()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Decoder<?> getSseDecoder() {
|
||||
if (this.sseDecoder != null) {
|
||||
return this.sseDecoder;
|
||||
}
|
||||
return (jackson2Present ? getJackson2JsonDecoder() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
List<HttpMessageWriter<?>> getTypedWriters() {
|
||||
if (!shouldRegisterDefaults()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> result = super.getTypedWriters();
|
||||
result.add(new MultipartHttpMessageWriter(getPartWriters(), new FormHttpMessageWriter()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<HttpMessageWriter<?>> getPartWriters() {
|
||||
List<HttpMessageWriter<?>> partWriters;
|
||||
if (this.multipartCodecs != null) {
|
||||
partWriters = this.multipartCodecs.getWriters();
|
||||
}
|
||||
else {
|
||||
DefaultCustomCodecs customCodecs = getCustomCodecs();
|
||||
partWriters = new ArrayList<>(super.getTypedWriters());
|
||||
if (customCodecs != null) {
|
||||
partWriters.addAll(customCodecs.getTypedWriters());
|
||||
}
|
||||
partWriters.addAll(super.getObjectWriters());
|
||||
if (customCodecs != null) {
|
||||
partWriters.addAll(customCodecs.getObjectWriters());
|
||||
}
|
||||
partWriters.addAll(super.getCatchAllWriters());
|
||||
}
|
||||
return partWriters;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultMultipartCodecs implements MultipartCodecs {
|
||||
|
||||
private final List<HttpMessageWriter<?>> writers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public MultipartCodecs encoder(Encoder<?> encoder) {
|
||||
writer(new EncoderHttpMessageWriter<>(encoder));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultipartCodecs writer(HttpMessageWriter<?> writer) {
|
||||
this.writers.add(writer);
|
||||
return this;
|
||||
}
|
||||
|
||||
List<HttpMessageWriter<?>> getWriters() {
|
||||
return this.writers;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,19 +16,7 @@
|
||||
|
||||
package org.springframework.http.codec.support;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.http.codec.FormHttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
||||
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
||||
import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ServerCodecConfigurer}.
|
||||
@@ -36,11 +24,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements ServerCodecConfigurer {
|
||||
|
||||
static final boolean synchronossMultipartPresent =
|
||||
ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser",
|
||||
DefaultServerCodecConfigurer.class.getClassLoader());
|
||||
public class DefaultServerCodecConfigurer extends BaseCodecConfigurer implements ServerCodecConfigurer {
|
||||
|
||||
|
||||
public DefaultServerCodecConfigurer() {
|
||||
@@ -52,52 +36,4 @@ public class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implem
|
||||
return (ServerDefaultCodecs) super.defaultCodecs();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ServerDefaultCodecs}.
|
||||
*/
|
||||
private static class ServerDefaultCodecsImpl extends AbstractDefaultCodecs implements ServerDefaultCodecs {
|
||||
|
||||
@Nullable
|
||||
private Encoder<?> sseEncoder;
|
||||
|
||||
@Override
|
||||
public void serverSentEventEncoder(Encoder<?> encoder) {
|
||||
this.sseEncoder = encoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<HttpMessageReader<?>> getTypedReaders() {
|
||||
if (!shouldRegisterDefaults()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageReader<?>> result = super.getTypedReaders();
|
||||
result.add(new FormHttpMessageReader());
|
||||
if (synchronossMultipartPresent) {
|
||||
SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader();
|
||||
result.add(partReader);
|
||||
result.add(new MultipartHttpMessageReader(partReader));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
List<HttpMessageWriter<?>> getObjectWriters() {
|
||||
if (!shouldRegisterDefaults()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<HttpMessageWriter<?>> result = super.getObjectWriters();
|
||||
result.add(new ServerSentEventHttpMessageWriter(getSseEncoder()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Encoder<?> getSseEncoder() {
|
||||
if (this.sseEncoder != null) {
|
||||
return this.sseEncoder;
|
||||
}
|
||||
return jackson2Present ? getJackson2JsonEncoder() : null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2002-2018 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.support;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
|
||||
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
||||
import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ServerCodecConfigurer.ServerDefaultCodecs}.
|
||||
*/
|
||||
class ServerDefaultCodecsImpl extends BaseDefaultCodecs implements ServerCodecConfigurer.ServerDefaultCodecs {
|
||||
|
||||
private static final boolean synchronossMultipartPresent =
|
||||
ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser",
|
||||
DefaultServerCodecConfigurer.class.getClassLoader());
|
||||
|
||||
|
||||
@Nullable
|
||||
private Encoder<?> sseEncoder;
|
||||
|
||||
|
||||
@Override
|
||||
public void serverSentEventEncoder(Encoder<?> encoder) {
|
||||
this.sseEncoder = encoder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void extendTypedReaders(List<HttpMessageReader<?>> typedReaders) {
|
||||
if (synchronossMultipartPresent) {
|
||||
SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader();
|
||||
typedReaders.add(partReader);
|
||||
typedReaders.add(new MultipartHttpMessageReader(partReader));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extendObjectWriters(List<HttpMessageWriter<?>> objectWriters) {
|
||||
objectWriters.add(new ServerSentEventHttpMessageWriter(getSseEncoder()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Encoder<?> getSseEncoder() {
|
||||
return this.sseEncoder != null ? this.sseEncoder : jackson2Present ? getJackson2JsonEncoder() : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.ClientCodecConfigurer;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.FormHttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||
@@ -74,12 +75,13 @@ public class ClientCodecConfigurerTests {
|
||||
@Test
|
||||
public void defaultReaders() {
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
assertEquals(10, readers.size());
|
||||
assertEquals(11, 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(FormHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass());
|
||||
assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass());
|
||||
assertEquals(Jackson2SmileDecoder.class, getNextDecoder(readers).getClass());
|
||||
assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass());
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.CodecConfigurer;
|
||||
import org.springframework.http.codec.DecoderHttpMessageReader;
|
||||
import org.springframework.http.codec.EncoderHttpMessageWriter;
|
||||
import org.springframework.http.codec.FormHttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageReader;
|
||||
import org.springframework.http.codec.HttpMessageWriter;
|
||||
import org.springframework.http.codec.ResourceHttpMessageWriter;
|
||||
@@ -53,7 +54,7 @@ import static org.mockito.Mockito.*;
|
||||
import static org.springframework.core.ResolvableType.forClass;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractCodecConfigurer.AbstractDefaultCodecs}.
|
||||
* Unit tests for {@link BaseCodecConfigurer}.
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class CodecConfigurerTests {
|
||||
@@ -66,12 +67,13 @@ public class CodecConfigurerTests {
|
||||
@Test
|
||||
public void defaultReaders() {
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
assertEquals(9, readers.size());
|
||||
assertEquals(10, 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(FormHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass());
|
||||
assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass());
|
||||
assertEquals(Jackson2SmileDecoder.class, getNextDecoder(readers).getClass());
|
||||
assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass());
|
||||
@@ -115,12 +117,13 @@ public class CodecConfigurerTests {
|
||||
|
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
|
||||
|
||||
assertEquals(13, readers.size());
|
||||
assertEquals(14, 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(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass());
|
||||
@@ -284,13 +287,13 @@ public class CodecConfigurerTests {
|
||||
|
||||
|
||||
|
||||
private static class TestCodecConfigurer extends AbstractCodecConfigurer {
|
||||
private static class TestCodecConfigurer extends BaseCodecConfigurer {
|
||||
|
||||
TestCodecConfigurer() {
|
||||
super(new TestDefaultCodecs());
|
||||
}
|
||||
|
||||
private static class TestDefaultCodecs extends AbstractDefaultCodecs {
|
||||
private static class TestDefaultCodecs extends BaseDefaultCodecs {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user