提交 682186a2 编写于 作者: J Juergen Hoeller

Refactored CodecConfigurer creation for clearer subpackage interdependencies

Includes redeclaration of CodecConfigurer.DefaultCodecs without concrete Jackson decoder/encoder references in order to avoid hard Jackson dependency.

Issue: SPR-16064
上级 faa74988
......@@ -35,17 +35,15 @@ import org.springframework.core.codec.Encoder;
*/
public interface ClientCodecConfigurer extends CodecConfigurer {
@Override
ClientDefaultCodecs defaultCodecs();
/**
* Creates a new instance of the {@code ClientCodecConfigurer}.
* @return the created instance
* Create a new instance of the {@code ClientCodecConfigurer}.
*/
static ClientCodecConfigurer create() {
return new DefaultClientCodecConfigurer();
return CodecConfigurerFactory.create(ClientCodecConfigurer.class);
}
......@@ -71,6 +69,7 @@ public interface ClientCodecConfigurer extends CodecConfigurer {
void serverSentEventDecoder(Decoder<?> decoder);
}
/**
* Registry and container for multipart HTTP message writers.
*/
......
......@@ -20,8 +20,6 @@ import java.util.List;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.Encoder;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
/**
* Defines a common interface for configuring either client or server HTTP
......@@ -73,15 +71,16 @@ public interface CodecConfigurer {
/**
* Override the default Jackson JSON {@code Decoder}.
* @param decoder the decoder instance to use
* @see org.springframework.http.codec.json.Jackson2JsonDecoder
*/
void jackson2JsonDecoder(Jackson2JsonDecoder decoder);
void jackson2JsonDecoder(Decoder<?> decoder);
/**
* Override the default Jackson JSON {@code Encoder}.
* @param encoder the encoder instance to use
* @see org.springframework.http.codec.json.Jackson2JsonEncoder
*/
void jackson2JsonEncoder(Jackson2JsonEncoder encoder);
void jackson2JsonEncoder(Encoder<?> encoder);
}
......@@ -119,6 +118,6 @@ public interface CodecConfigurer {
* @param writer the writer to add
*/
void writer(HttpMessageWriter<?> writer);
}
}
/*
* 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.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.ClassUtils;
/**
* Internal delegate for loading the default codec configurer class names.
* Models a loose relationship with the default implementations in the support
* package, literally only needing to know the default class name to use.
*
* @author Juergen Hoeller
* @since 5.0.1
* @see ClientCodecConfigurer#create()
* @see ServerCodecConfigurer#create()
*/
class CodecConfigurerFactory {
private static final String DEFAULT_CONFIGURERS_PATH = "CodecConfigurer.properties";
private static final Map<Class<?>, Class<?>> defaultCodecConfigurers = new HashMap<>(4);
static {
try {
Properties props = PropertiesLoaderUtils.loadProperties(
new ClassPathResource(DEFAULT_CONFIGURERS_PATH, CodecConfigurerFactory.class));
for (String ifcName : props.stringPropertyNames()) {
String implName = props.getProperty(ifcName);
Class<?> ifc = ClassUtils.forName(ifcName, CodecConfigurerFactory.class.getClassLoader());
Class<?> impl = ClassUtils.forName(implName, CodecConfigurerFactory.class.getClassLoader());
defaultCodecConfigurers.put(ifc, impl);
}
}
catch (IOException | ClassNotFoundException ex) {
throw new IllegalStateException(ex);
}
}
@SuppressWarnings("unchecked")
public static <T extends CodecConfigurer> T create(Class<T> ifc) {
Class<?> impl = defaultCodecConfigurers.get(ifc);
if (impl == null) {
throw new IllegalStateException("No default codec configurer found for " + ifc);
}
return (T) BeanUtils.instantiateClass(impl);
}
}
......@@ -39,11 +39,10 @@ public interface ServerCodecConfigurer extends CodecConfigurer {
/**
* Creates a new instance of the {@code ServerCodecConfigurer}.
* @return the created instance
* Create a new instance of the {@code ServerCodecConfigurer}.
*/
static ServerCodecConfigurer create() {
return new DefaultServerCodecConfigurer();
return CodecConfigurerFactory.create(ServerCodecConfigurer.class);
}
......
......@@ -18,7 +18,6 @@ package org.springframework.http.codec;
import java.time.Duration;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.lang.Nullable;
/**
......@@ -167,10 +166,10 @@ public class ServerSentEvent<T> {
Builder<T> comment(String comment);
/**
* Set the value of the {@code data} field. If the {@code data} argument is a
* multi-line {@code String}, it will be turned into multiple {@code data} field lines
* as defined in the Server-Sent Events W3C recommendation. If {@code data} is not a
* String, it will be {@linkplain Jackson2JsonEncoder encoded} into JSON.
* Set the value of the {@code data} field. If the {@code data} argument is a multi-line
* {@code String}, it will be turned into multiple {@code data} field lines as defined
* in the Server-Sent Events W3C recommendation. If {@code data} is not a String, it will
* be {@linkplain org.springframework.http.codec.json.Jackson2JsonEncoder encoded} into JSON.
* @param data the value of the data field
* @return {@code this} builder
*/
......@@ -181,9 +180,9 @@ public class ServerSentEvent<T> {
* @return the built event
*/
ServerSentEvent<T> build();
}
private static class BuilderImpl<T> implements Builder<T> {
@Nullable
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.codec.json;
import java.io.IOException;
......@@ -54,7 +55,6 @@ import org.springframework.util.MimeType;
*/
public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport implements HttpMessageDecoder<Object> {
/**
* Constructor with a Jackson {@link ObjectMapper} to use.
*/
......@@ -144,4 +144,5 @@ public abstract class AbstractJackson2Decoder extends Jackson2CodecSupport imple
protected <A extends Annotation> A getAnnotation(MethodParameter parameter, Class<A> annotType) {
return parameter.getParameterAnnotation(annotType);
}
}
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.codec.json;
import java.io.IOException;
......@@ -57,6 +58,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
protected final List<MediaType> streamingMediaTypes = new ArrayList<>(1);
/**
* Constructor with a Jackson {@link ObjectMapper} to use.
*/
......@@ -64,6 +66,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
super(mapper, mimeTypes);
}
/**
* Configure "streaming" media types for which flushing should be performed
* automatically vs at the end of the stream.
......@@ -76,6 +79,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
this.streamingMediaTypes.addAll(mediaTypes);
}
@Override
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
Class<?> clazz = elementType.resolve(Object.class);
......@@ -143,6 +147,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
protected ObjectWriter customizeWriter(ObjectWriter writer, @Nullable MimeType mimeType,
ResolvableType elementType, @Nullable Map<String, Object> hints) {
return writer;
}
......
......@@ -83,7 +83,7 @@ public abstract class Jackson2CodecSupport {
}
/**
* Sub-classes should expose this as "decodable" or "encodable" mime types.
* Subclasses should expose this as "decodable" or "encodable" mime types.
*/
protected List<MimeType> getMimeTypes() {
return this.mimeTypes;
......
......@@ -19,6 +19,7 @@ package org.springframework.http.codec.json;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.util.MimeType;
......@@ -40,8 +41,10 @@ public class Jackson2JsonDecoder extends AbstractJackson2Decoder {
super(mapper, mimeTypes);
}
@Override
public List<MimeType> getDecodableMimeTypes() {
return getMimeTypes();
}
}
......@@ -63,16 +63,20 @@ public class Jackson2JsonEncoder extends AbstractJackson2Encoder {
return printer;
}
@Override
protected ObjectWriter customizeWriter(ObjectWriter writer, @Nullable MimeType mimeType,
ResolvableType elementType, @Nullable Map<String, Object> hints) {
return (this.ssePrettyPrinter != null && MediaType.TEXT_EVENT_STREAM.isCompatibleWith(mimeType) &&
writer.getConfig().isEnabled(SerializationFeature.INDENT_OUTPUT) ? writer.with(this.ssePrettyPrinter) : writer);
return (this.ssePrettyPrinter != null &&
MediaType.TEXT_EVENT_STREAM.isCompatibleWith(mimeType) &&
writer.getConfig().isEnabled(SerializationFeature.INDENT_OUTPUT) ?
writer.with(this.ssePrettyPrinter) : writer);
}
@Override
public List<MimeType> getEncodableMimeTypes() {
return getMimeTypes();
}
}
......@@ -16,7 +16,7 @@
package org.springframework.http.codec.json;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
......@@ -51,6 +51,7 @@ public class Jackson2SmileDecoder extends AbstractJackson2Decoder {
@Override
public List<MimeType> getDecodableMimeTypes() {
return Arrays.asList(SMILE_MIME_TYPE);
return Collections.singletonList(SMILE_MIME_TYPE);
}
}
......@@ -16,7 +16,7 @@
package org.springframework.http.codec.json;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
......@@ -49,8 +49,10 @@ public class Jackson2SmileEncoder extends AbstractJackson2Encoder {
this.streamingMediaTypes.add(new MediaType("application", "stream+x-jackson-smile"));
}
@Override
public List<MimeType> getEncodableMimeTypes() {
return Arrays.asList(SMILE_MIME_TYPE);
return Collections.singletonList(SMILE_MIME_TYPE);
}
}
......@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.http.codec;
package org.springframework.http.codec.support;
import java.util.ArrayList;
import java.util.Collections;
......@@ -32,6 +32,12 @@ 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;
......@@ -50,7 +56,7 @@ import org.springframework.util.ClassUtils;
*/
abstract class AbstractCodecConfigurer implements CodecConfigurer {
protected static final boolean jackson2Present =
static final boolean jackson2Present =
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
AbstractCodecConfigurer.class.getClassLoader()) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
......@@ -60,8 +66,8 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory",
AbstractCodecConfigurer.class.getClassLoader());
protected static final boolean jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder",
AbstractCodecConfigurer.class.getClassLoader());
private static final boolean jaxb2Present =
ClassUtils.isPresent("javax.xml.bind.Binder", AbstractCodecConfigurer.class.getClassLoader());
private final AbstractDefaultCodecs defaultCodecs;
......@@ -69,7 +75,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
private final DefaultCustomCodecs customCodecs = new DefaultCustomCodecs();
protected AbstractCodecConfigurer(AbstractDefaultCodecs defaultCodecs) {
AbstractCodecConfigurer(AbstractDefaultCodecs defaultCodecs) {
Assert.notNull(defaultCodecs, "'defaultCodecs' is required");
this.defaultCodecs = defaultCodecs;
this.defaultCodecs.setCustomCodecs(this.customCodecs);
......@@ -83,7 +89,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
@Override
public void registerDefaults(boolean shouldRegister) {
this.defaultCodecs.setRegisterDefaults(shouldRegister);
this.defaultCodecs.registerDefaults(shouldRegister);
}
@Override
......@@ -120,60 +126,60 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
}
abstract protected static class AbstractDefaultCodecs implements DefaultCodecs {
abstract static class AbstractDefaultCodecs implements DefaultCodecs {
private boolean registerDefaults = true;
@Nullable
private Jackson2JsonDecoder jackson2JsonDecoder;
private Decoder<?> jackson2JsonDecoder;
@Nullable
private Jackson2JsonEncoder jackson2JsonEncoder;
private Encoder<?> jackson2JsonEncoder;
@Nullable
private DefaultCustomCodecs customCodecs;
public void setRegisterDefaults(boolean registerDefaults) {
void registerDefaults(boolean registerDefaults) {
this.registerDefaults = registerDefaults;
}
public boolean shouldRegisterDefaults() {
boolean shouldRegisterDefaults() {
return this.registerDefaults;
}
/**
* Access to custom codecs for sub-classes, e.g. for multipart writers.
* Access to custom codecs for subclasses, e.g. for multipart writers.
*/
public void setCustomCodecs(@Nullable DefaultCustomCodecs customCodecs) {
void setCustomCodecs(@Nullable DefaultCustomCodecs customCodecs) {
this.customCodecs = customCodecs;
}
@Nullable
public DefaultCustomCodecs getCustomCodecs() {
DefaultCustomCodecs getCustomCodecs() {
return this.customCodecs;
}
@Override
public void jackson2JsonDecoder(Jackson2JsonDecoder decoder) {
public void jackson2JsonDecoder(Decoder<?> decoder) {
this.jackson2JsonDecoder = decoder;
}
protected Jackson2JsonDecoder jackson2JsonDecoder() {
Decoder<?> getJackson2JsonDecoder() {
return (this.jackson2JsonDecoder != null ? this.jackson2JsonDecoder : new Jackson2JsonDecoder());
}
@Override
public void jackson2JsonEncoder(Jackson2JsonEncoder encoder) {
public void jackson2JsonEncoder(Encoder<?> encoder) {
this.jackson2JsonEncoder = encoder;
}
protected Jackson2JsonEncoder jackson2JsonEncoder() {
Encoder<?> getJackson2JsonEncoder() {
return (this.jackson2JsonEncoder != null ? this.jackson2JsonEncoder : new Jackson2JsonEncoder());
}
// Readers...
public List<HttpMessageReader<?>> getTypedReaders() {
List<HttpMessageReader<?>> getTypedReaders() {
if (!this.registerDefaults) {
return Collections.emptyList();
}
......@@ -186,26 +192,26 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
return result;
}
protected abstract boolean splitTextOnNewLine();
abstract boolean splitTextOnNewLine();
public List<HttpMessageReader<?>> getObjectReaders() {
List<HttpMessageReader<?>> getObjectReaders() {
if (!this.registerDefaults) {
return Collections.emptyList();
}
List<HttpMessageReader<?>> result = new ArrayList<>();
if (jaxb2Present) {
result.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
}
if (jackson2Present) {
result.add(new DecoderHttpMessageReader<>(jackson2JsonDecoder()));
result.add(new DecoderHttpMessageReader<>(getJackson2JsonDecoder()));
}
if (jackson2SmilePresent) {
result.add(new DecoderHttpMessageReader<>(new Jackson2SmileDecoder()));
}
if (jaxb2Present) {
result.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder()));
}
return result;
}
public List<HttpMessageReader<?>> getCatchAllReaders() {
List<HttpMessageReader<?>> getCatchAllReaders() {
if (!this.registerDefaults) {
return Collections.emptyList();
}
......@@ -216,7 +222,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
// Writers...
public List<HttpMessageWriter<?>> getTypedWriters() {
List<HttpMessageWriter<?>> getTypedWriters() {
if (!this.registerDefaults) {
return Collections.emptyList();
}
......@@ -229,24 +235,24 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
return result;
}
public List<HttpMessageWriter<?>> getObjectWriters() {
List<HttpMessageWriter<?>> getObjectWriters() {
if (!this.registerDefaults) {
return Collections.emptyList();
}
List<HttpMessageWriter<?>> result = new ArrayList<>();
if (jaxb2Present) {
result.add(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
}
if (jackson2Present) {
result.add(new EncoderHttpMessageWriter<>(jackson2JsonEncoder()));
result.add(new EncoderHttpMessageWriter<>(getJackson2JsonEncoder()));
}
if (jackson2SmilePresent) {
result.add(new EncoderHttpMessageWriter<>(new Jackson2SmileEncoder()));
}
if (jaxb2Present) {
result.add(new EncoderHttpMessageWriter<>(new Jaxb2XmlEncoder()));
}
return result;
}
public List<HttpMessageWriter<?>> getCatchAllWriters() {
List<HttpMessageWriter<?>> getCatchAllWriters() {
if (!this.registerDefaults) {
return Collections.emptyList();
}
......@@ -257,7 +263,7 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
}
protected static class DefaultCustomCodecs implements CustomCodecs {
static class DefaultCustomCodecs implements CustomCodecs {
private final List<HttpMessageReader<?>> typedReaders = new ArrayList<>();
......@@ -289,19 +295,19 @@ abstract class AbstractCodecConfigurer implements CodecConfigurer {
(canWriteObject ? this.objectWriters : this.typedWriters).add(writer);
}
public List<HttpMessageReader<?>> getTypedReaders() {
List<HttpMessageReader<?>> getTypedReaders() {
return this.typedReaders;
}
public List<HttpMessageWriter<?>> getTypedWriters() {
List<HttpMessageWriter<?>> getTypedWriters() {
return this.typedWriters;
}
public List<HttpMessageReader<?>> getObjectReaders() {
List<HttpMessageReader<?>> getObjectReaders() {
return this.objectReaders;
}
public List<HttpMessageWriter<?>> getObjectWriters() {
List<HttpMessageWriter<?>> getObjectWriters() {
return this.objectWriters;
}
}
......
......@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.http.codec;
package org.springframework.http.codec.support;
import java.util.ArrayList;
import java.util.Collections;
......@@ -22,6 +22,12 @@ 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;
......@@ -31,7 +37,7 @@ import org.springframework.lang.Nullable;
* @author Rossen Stoyanchev
* @since 5.0
*/
class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements ClientCodecConfigurer {
public class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements ClientCodecConfigurer {
public DefaultClientCodecConfigurer() {
super(new ClientDefaultCodecsImpl());
......@@ -65,12 +71,12 @@ class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements Cl
}
@Override
protected boolean splitTextOnNewLine() {
boolean splitTextOnNewLine() {
return false;
}
@Override
public List<HttpMessageReader<?>> getObjectReaders() {
List<HttpMessageReader<?>> getObjectReaders() {
if (!shouldRegisterDefaults()) {
return Collections.emptyList();
}
......@@ -84,12 +90,12 @@ class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements Cl
if (this.sseDecoder != null) {
return this.sseDecoder;
}
return (jackson2Present ? jackson2JsonDecoder() : null);
return (jackson2Present ? getJackson2JsonDecoder() : null);
}
@Override
public List<HttpMessageWriter<?>> getTypedWriters() {
if (!this.shouldRegisterDefaults()) {
List<HttpMessageWriter<?>> getTypedWriters() {
if (!shouldRegisterDefaults()) {
return Collections.emptyList();
}
List<HttpMessageWriter<?>> result = super.getTypedWriters();
......@@ -137,7 +143,7 @@ class DefaultClientCodecConfigurer extends AbstractCodecConfigurer implements Cl
return this;
}
public List<HttpMessageWriter<?>> getWriters() {
List<HttpMessageWriter<?>> getWriters() {
return this.writers;
}
}
......
......@@ -14,12 +14,17 @@
* limitations under the License.
*/
package org.springframework.http.codec;
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;
......@@ -31,11 +36,11 @@ import org.springframework.util.ClassUtils;
* @author Rossen Stoyanchev
* @since 5.0
*/
class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements ServerCodecConfigurer {
public class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements ServerCodecConfigurer {
static final boolean synchronossMultipartPresent = ClassUtils.isPresent(
"org.synchronoss.cloud.nio.multipart.NioMultipartParser",
DefaultServerCodecConfigurer.class.getClassLoader());
static final boolean synchronossMultipartPresent =
ClassUtils.isPresent("org.synchronoss.cloud.nio.multipart.NioMultipartParser",
DefaultServerCodecConfigurer.class.getClassLoader());
public DefaultServerCodecConfigurer() {
......@@ -62,12 +67,12 @@ class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements Se
}
@Override
protected boolean splitTextOnNewLine() {
boolean splitTextOnNewLine() {
return true;
}
@Override
public List<HttpMessageReader<?>> getTypedReaders() {
List<HttpMessageReader<?>> getTypedReaders() {
if (!shouldRegisterDefaults()) {
return Collections.emptyList();
}
......@@ -82,7 +87,7 @@ class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements Se
}
@Override
public List<HttpMessageWriter<?>> getObjectWriters() {
List<HttpMessageWriter<?>> getObjectWriters() {
if (!shouldRegisterDefaults()) {
return Collections.emptyList();
}
......@@ -96,7 +101,7 @@ class DefaultServerCodecConfigurer extends AbstractCodecConfigurer implements Se
if (this.sseEncoder != null) {
return this.sseEncoder;
}
return jackson2Present ? jackson2JsonEncoder() : null;
return jackson2Present ? getJackson2JsonEncoder() : null;
}
}
......
/**
* Provides implementations of {@link org.springframework.http.codec.ClientCodecConfigurer}
* and {@link org.springframework.http.codec.ServerCodecConfigurer} based on the converter
* implementations from {@code org.springframework.http.codec.json} and co.
*/
@NonNullApi
@NonNullFields
package org.springframework.http.codec.support;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
# Default CodecConfigurer implementation classes for static Client/ServerCodecConfigurer.create() calls.
# Not meant to be customized by application developers; simply instantiate custom impl classes instead.
org.springframework.http.codec.ClientCodecConfigurer=org.springframework.http.codec.support.DefaultClientCodecConfigurer
org.springframework.http.codec.ServerCodecConfigurer=org.springframework.http.codec.support.DefaultServerCodecConfigurer
......@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.codec;
package org.springframework.http.codec.support;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
......@@ -38,6 +39,14 @@ import org.springframework.core.codec.ResourceDecoder;
import org.springframework.core.codec.StringDecoder;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
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.FormHttpMessageWriter;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.codec.ResourceHttpMessageWriter;
import org.springframework.http.codec.ServerSentEventHttpMessageReader;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.http.codec.json.Jackson2SmileDecoder;
......@@ -48,10 +57,11 @@ import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.*;
import static org.springframework.core.ResolvableType.forClass;
import static org.springframework.core.ResolvableType.*;
/**
* Unit tests for {@link ClientCodecConfigurer}.
*
* @author Rossen Stoyanchev
*/
public class ClientCodecConfigurerTests {
......@@ -62,7 +72,7 @@ public class ClientCodecConfigurerTests {
@Test
public void defaultReaders() throws Exception {
public void defaultReaders() {
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertEquals(10, readers.size());
assertEquals(ByteArrayDecoder.class, getNextDecoder(readers).getClass());
......@@ -70,15 +80,15 @@ public class ClientCodecConfigurerTests {
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());
assertEquals(Jackson2SmileDecoder.class, getNextDecoder(readers).getClass());
assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass());
assertSseReader(readers);
assertStringDecoder(getNextDecoder(readers), false);
}
@Test
public void defaultWriters() throws Exception {
public void defaultWriters() {
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
assertEquals(11, writers.size());
assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass());
......@@ -88,15 +98,14 @@ public class ClientCodecConfigurerTests {
assertStringEncoder(getNextEncoder(writers), true);
assertEquals(FormHttpMessageWriter.class, writers.get(this.index.getAndIncrement()).getClass());
assertEquals(MultipartHttpMessageWriter.class, writers.get(this.index.getAndIncrement()).getClass());
assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass());
assertEquals(Jackson2JsonEncoder.class, getNextEncoder(writers).getClass());
assertEquals(Jackson2SmileEncoder.class, getNextEncoder(writers).getClass());
assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass());
assertStringEncoder(getNextEncoder(writers), false);
}
@Test
public void jackson2EncoderOverride() throws Exception {
public void jackson2EncoderOverride() {
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder();
this.configurer.defaultCodecs().jackson2JsonDecoder(decoder);
......
......@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.codec;
package org.springframework.http.codec.support;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -33,6 +34,12 @@ 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.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;
......@@ -41,12 +48,9 @@ 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;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.springframework.core.ResolvableType.*;
/**
* Unit tests for {@link AbstractCodecConfigurer.AbstractDefaultCodecs}.
......@@ -60,7 +64,7 @@ public class CodecConfigurerTests {
@Test
public void defaultReaders() throws Exception {
public void defaultReaders() {
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertEquals(9, readers.size());
assertEquals(ByteArrayDecoder.class, getNextDecoder(readers).getClass());
......@@ -68,14 +72,14 @@ public class CodecConfigurerTests {
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());
assertEquals(Jackson2SmileDecoder.class, getNextDecoder(readers).getClass());
assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass());
assertStringDecoder(getNextDecoder(readers), false);
}
@Test
public void defaultWriters() throws Exception {
public void defaultWriters() {
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
assertEquals(9, writers.size());
assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass());
......@@ -83,15 +87,14 @@ public class CodecConfigurerTests {
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());
assertEquals(Jackson2SmileEncoder.class, getNextEncoder(writers).getClass());
assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass());
assertStringEncoder(getNextEncoder(writers), false);
}
@Test
public void defaultAndCustomReaders() throws Exception {
public void defaultAndCustomReaders() {
Decoder<?> customDecoder1 = mock(Decoder.class);
Decoder<?> customDecoder2 = mock(Decoder.class);
......@@ -120,17 +123,16 @@ public class CodecConfigurerTests {
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());
assertEquals(Jackson2SmileDecoder.class, getNextDecoder(readers).getClass());
assertEquals(Jaxb2XmlDecoder.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 {
public void defaultAndCustomWriters() {
Encoder<?> customEncoder1 = mock(Encoder.class);
Encoder<?> customEncoder2 = mock(Encoder.class);
......@@ -159,17 +161,16 @@ public class CodecConfigurerTests {
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(Jackson2SmileEncoder.class, getNextEncoder(writers).getClass());
assertEquals(Jaxb2XmlEncoder.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 {
public void defaultsOffCustomReaders() {
Decoder<?> customDecoder1 = mock(Decoder.class);
Decoder<?> customDecoder2 = mock(Decoder.class);
......@@ -200,8 +201,7 @@ public class CodecConfigurerTests {
}
@Test
public void defaultsOffWithCustomWriters() throws Exception {
public void defaultsOffWithCustomWriters() {
Encoder<?> customEncoder1 = mock(Encoder.class);
Encoder<?> customEncoder2 = mock(Encoder.class);
......@@ -232,8 +232,7 @@ public class CodecConfigurerTests {
}
@Test
public void jackson2DecoderOverride() throws Exception {
public void jackson2DecoderOverride() {
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder();
this.configurer.defaultCodecs().jackson2JsonDecoder(decoder);
......@@ -246,8 +245,7 @@ public class CodecConfigurerTests {
}
@Test
public void jackson2EncoderOverride() throws Exception {
public void jackson2EncoderOverride() {
Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
this.configurer.defaultCodecs().jackson2JsonEncoder(encoder);
......@@ -295,7 +293,7 @@ public class CodecConfigurerTests {
private static class TestDefaultCodecs extends AbstractDefaultCodecs {
@Override
protected boolean splitTextOnNewLine() {
boolean splitTextOnNewLine() {
return true;
}
}
......
......@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.http.codec;
package org.springframework.http.codec.support;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
......@@ -39,6 +40,14 @@ import org.springframework.core.codec.ResourceDecoder;
import org.springframework.core.codec.StringDecoder;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.MediaType;
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.ServerCodecConfigurer;
import org.springframework.http.codec.ServerSentEventHttpMessageWriter;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.http.codec.json.Jackson2SmileDecoder;
......@@ -50,10 +59,11 @@ import org.springframework.http.codec.xml.Jaxb2XmlEncoder;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.*;
import static org.springframework.core.ResolvableType.forClass;
import static org.springframework.core.ResolvableType.*;
/**
* Unit tests for {@link ServerCodecConfigurer}.
*
* @author Rossen Stoyanchev
*/
public class ServerCodecConfigurerTests {
......@@ -64,7 +74,7 @@ public class ServerCodecConfigurerTests {
@Test
public void defaultReaders() throws Exception {
public void defaultReaders() {
List<HttpMessageReader<?>> readers = this.configurer.getReaders();
assertEquals(12, readers.size());
assertEquals(ByteArrayDecoder.class, getNextDecoder(readers).getClass());
......@@ -75,14 +85,14 @@ public class ServerCodecConfigurerTests {
assertEquals(FormHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass());
assertEquals(SynchronossPartHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass());
assertEquals(MultipartHttpMessageReader.class, readers.get(this.index.getAndIncrement()).getClass());
assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass());
assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass());
assertEquals(Jackson2SmileDecoder.class, getNextDecoder(readers).getClass());
assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass());
assertStringDecoder(getNextDecoder(readers), false);
}
@Test
public void defaultWriters() throws Exception {
public void defaultWriters() {
List<HttpMessageWriter<?>> writers = this.configurer.getWriters();
assertEquals(10, writers.size());
assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass());
......@@ -90,16 +100,15 @@ public class ServerCodecConfigurerTests {
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());
assertEquals(Jackson2SmileEncoder.class, getNextEncoder(writers).getClass());
assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass());
assertSseWriter(writers);
assertStringEncoder(getNextEncoder(writers), false);
}
@Test
public void jackson2EncoderOverride() throws Exception {
public void jackson2EncoderOverride() {
Jackson2JsonEncoder encoder = new Jackson2JsonEncoder();
this.configurer.defaultCodecs().jackson2JsonEncoder(encoder);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册