提交 6e5273f0 编写于 作者: R Rossen Stoyanchev

Polish CodecConfigurer support classes

Functionally equivalent updates to package private classes to improve
the code and make it easier to understand.
上级 1f8476aa
......@@ -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 {
......
/*
* 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.
*/
void registerDefaults(boolean registerDefaults);
CustomCodecs customCodecs();
/**
* Register custom HTTP message readers or writers to use in addition to
* the ones registered by default.
* 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.
*/
CustomCodecs customCodecs();
void registerDefaults(boolean registerDefaults);
/**
* 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 {
......
......@@ -17,68 +17,40 @@
package org.springframework.http.codec.support;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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.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}.
* Default implementation of {@link CodecConfigurer} that serves as a base for
* client and server specific variants.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
abstract class AbstractCodecConfigurer implements CodecConfigurer {
class BaseCodecConfigurer 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 BaseDefaultCodecs defaultCodecs;
private final DefaultCustomCodecs customCodecs = new DefaultCustomCodecs();
AbstractCodecConfigurer(AbstractDefaultCodecs defaultCodecs) {
/**
* 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;
this.defaultCodecs.setCustomCodecs(this.customCodecs);
}
......@@ -126,142 +98,21 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
}
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;
}
// Accessors for use in sub-classes...
// 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;
}
protected Supplier<List<HttpMessageWriter<?>>> getCustomTypedWriters() {
return () -> this.customCodecs.typedWriters;
}
List<HttpMessageWriter<?>> getCatchAllWriters() {
if (!this.registerDefaults) {
return Collections.emptyList();
}
List<HttpMessageWriter<?>> result = new ArrayList<>();
result.add(new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()));
return result;
}
protected Supplier<List<HttpMessageWriter<?>>> getCustomObjectWriters() {
return () -> this.customCodecs.objectWriters;
}
static class DefaultCustomCodecs implements CustomCodecs {
/**
* Default implementation of {@code CustomCodecs}.
*/
private static final class DefaultCustomCodecs implements CustomCodecs {
private final List<HttpMessageReader<?>> typedReaders = new ArrayList<>();
......@@ -271,6 +122,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
private final List<HttpMessageWriter<?>> objectWriters = new ArrayList<>();
@Override
public void decoder(Decoder<?> decoder) {
reader(new DecoderHttpMessageReader<>(decoder));
......@@ -293,6 +145,9 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
(canWriteObject ? this.objectWriters : this.typedWriters).add(writer);
}
// Package private accessors...
List<HttpMessageReader<?>> getTypedReaders() {
return this.typedReaders;
}
......
/*
* 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());
}
}
/*
* 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,21 +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.FormHttpMessageReader;
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}.
......@@ -38,118 +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<?>> getTypedReaders() {
if (!shouldRegisterDefaults()) {
return Collections.emptyList();
}
List<HttpMessageReader<?>> result = super.getTypedReaders();
result.add(new FormHttpMessageReader());
return result;
}
@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;
}
}
}
/*
* 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;
}
}
......@@ -53,7 +53,7 @@ import static org.mockito.Mockito.*;
import static org.springframework.core.ResolvableType.forClass;
/**
* Unit tests for {@link AbstractCodecConfigurer.AbstractDefaultCodecs}.
* Unit tests for {@link BaseDefaultCodecs}.
* @author Rossen Stoyanchev
*/
public class CodecConfigurerTests {
......@@ -284,13 +284,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 {
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册