Browse Source
Functionally equivalent updates to package private classes to improve the code and make it easier to understand.pull/1838/head
12 changed files with 666 additions and 529 deletions
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue