3 changed files with 224 additions and 64 deletions
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
/* |
||||
* Copyright 2002-2017 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.http.codec; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.core.codec.Decoder; |
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder; |
||||
|
||||
/** |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 5.0 |
||||
*/ |
||||
public class ClientCodecConfigurer extends AbstractCodecConfigurer { |
||||
|
||||
|
||||
public ClientCodecConfigurer() { |
||||
super(new ClientDefaultCodecConfigurer()); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public ClientDefaultCodecConfigurer defaultCodec() { |
||||
return (ClientDefaultCodecConfigurer) super.defaultCodec(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
protected void addDefaultTypedWriter(List<HttpMessageWriter<?>> result) { |
||||
super.addDefaultTypedWriter(result); |
||||
defaultCodec().addWriterTo(result, FormHttpMessageWriter::new); |
||||
} |
||||
|
||||
@Override |
||||
protected void addDefaultObjectReaders(List<HttpMessageReader<?>> result) { |
||||
super.addDefaultObjectReaders(result); |
||||
defaultCodec().addServerSentEventReaderTo(result); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Extension of {@code DefaultCodecConfigurer} with extra client options. |
||||
*/ |
||||
public static class ClientDefaultCodecConfigurer extends DefaultCodecConfigurer { |
||||
|
||||
/** |
||||
* Configure the {@code Decoder} to use for Server-Sent Events. |
||||
* <p>By default the {@link #jackson2Decoder} override is used for SSE. |
||||
* @param decoder the decoder to use |
||||
*/ |
||||
public void serverSentEventDecoder(Decoder<?> decoder) { |
||||
HttpMessageReader<?> reader = new ServerSentEventHttpMessageReader(decoder); |
||||
getReaders().put(ServerSentEventHttpMessageReader.class, reader); |
||||
} |
||||
|
||||
|
||||
// Internal methods for building a list of default readers or writers...
|
||||
|
||||
private void addServerSentEventReaderTo(List<HttpMessageReader<?>> result) { |
||||
addReaderTo(result, () -> findReader(ServerSentEventHttpMessageReader.class, () -> { |
||||
Decoder<?> decoder = null; |
||||
if (jackson2Present) { |
||||
decoder = findDecoderReader( |
||||
Jackson2JsonDecoder.class, Jackson2JsonDecoder::new).getDecoder(); |
||||
} |
||||
return new ServerSentEventHttpMessageReader(decoder); |
||||
})); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
/* |
||||
* Copyright 2002-2017 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.http.codec; |
||||
|
||||
import java.util.List; |
||||
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.core.codec.ByteArrayDecoder; |
||||
import org.springframework.core.codec.ByteArrayEncoder; |
||||
import org.springframework.core.codec.ByteBufferDecoder; |
||||
import org.springframework.core.codec.ByteBufferEncoder; |
||||
import org.springframework.core.codec.CharSequenceEncoder; |
||||
import org.springframework.core.codec.DataBufferDecoder; |
||||
import org.springframework.core.codec.DataBufferEncoder; |
||||
import org.springframework.core.codec.Decoder; |
||||
import org.springframework.core.codec.Encoder; |
||||
import org.springframework.core.codec.ResourceDecoder; |
||||
import org.springframework.core.codec.StringDecoder; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder; |
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder; |
||||
import org.springframework.http.codec.xml.Jaxb2XmlDecoder; |
||||
import org.springframework.http.codec.xml.Jaxb2XmlEncoder; |
||||
import org.springframework.util.MimeTypeUtils; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertNotNull; |
||||
import static org.junit.Assert.assertSame; |
||||
import static org.junit.Assert.assertTrue; |
||||
import static org.springframework.core.ResolvableType.forClass; |
||||
|
||||
/** |
||||
* Unit tests for {@link ClientCodecConfigurer}. |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class ClientCodecConfigurerTests { |
||||
|
||||
private final ClientCodecConfigurer configurer = new ClientCodecConfigurer(); |
||||
|
||||
private final AtomicInteger index = new AtomicInteger(0); |
||||
|
||||
|
||||
@Test |
||||
public void defaultReaders() throws Exception { |
||||
List<HttpMessageReader<?>> readers = this.configurer.getReaders(); |
||||
assertEquals(9, readers.size()); |
||||
assertEquals(ByteArrayDecoder.class, getNextDecoder(readers).getClass()); |
||||
assertEquals(ByteBufferDecoder.class, getNextDecoder(readers).getClass()); |
||||
assertEquals(DataBufferDecoder.class, getNextDecoder(readers).getClass()); |
||||
assertEquals(ResourceDecoder.class, getNextDecoder(readers).getClass()); |
||||
assertStringDecoder(getNextDecoder(readers), true); |
||||
assertEquals(Jaxb2XmlDecoder.class, getNextDecoder(readers).getClass()); |
||||
assertEquals(Jackson2JsonDecoder.class, getNextDecoder(readers).getClass()); |
||||
assertSseReader(readers); |
||||
assertStringDecoder(getNextDecoder(readers), false); |
||||
} |
||||
|
||||
@Test |
||||
public void defaultWriters() throws Exception { |
||||
List<HttpMessageWriter<?>> writers = this.configurer.getWriters(); |
||||
assertEquals(9, writers.size()); |
||||
assertEquals(ByteArrayEncoder.class, getNextEncoder(writers).getClass()); |
||||
assertEquals(ByteBufferEncoder.class, getNextEncoder(writers).getClass()); |
||||
assertEquals(DataBufferEncoder.class, getNextEncoder(writers).getClass()); |
||||
assertEquals(ResourceHttpMessageWriter.class, writers.get(index.getAndIncrement()).getClass()); |
||||
assertStringEncoder(getNextEncoder(writers), true); |
||||
assertEquals(FormHttpMessageWriter.class, writers.get(this.index.getAndIncrement()).getClass()); |
||||
assertEquals(Jaxb2XmlEncoder.class, getNextEncoder(writers).getClass()); |
||||
assertEquals(Jackson2JsonEncoder.class, getNextEncoder(writers).getClass()); |
||||
assertStringEncoder(getNextEncoder(writers), false); |
||||
} |
||||
|
||||
@Test |
||||
public void jackson2EncoderOverride() throws Exception { |
||||
|
||||
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(); |
||||
this.configurer.defaultCodec().jackson2Decoder(decoder); |
||||
|
||||
assertSame(decoder, this.configurer.getReaders().stream() |
||||
.filter(reader -> ServerSentEventHttpMessageReader.class.equals(reader.getClass())) |
||||
.map(reader -> (ServerSentEventHttpMessageReader) reader) |
||||
.findFirst() |
||||
.map(ServerSentEventHttpMessageReader::getDecoder) |
||||
.filter(e -> e == decoder).orElse(null)); |
||||
} |
||||
|
||||
|
||||
private Decoder<?> getNextDecoder(List<HttpMessageReader<?>> readers) { |
||||
HttpMessageReader<?> reader = readers.get(this.index.getAndIncrement()); |
||||
assertEquals(DecoderHttpMessageReader.class, reader.getClass()); |
||||
return ((DecoderHttpMessageReader) reader).getDecoder(); |
||||
} |
||||
|
||||
private Encoder<?> getNextEncoder(List<HttpMessageWriter<?>> writers) { |
||||
HttpMessageWriter<?> writer = writers.get(this.index.getAndIncrement()); |
||||
assertEquals(EncoderHttpMessageWriter.class, writer.getClass()); |
||||
return ((EncoderHttpMessageWriter) writer).getEncoder(); |
||||
} |
||||
|
||||
private void assertStringDecoder(Decoder<?> decoder, boolean textOnly) { |
||||
assertEquals(StringDecoder.class, decoder.getClass()); |
||||
assertTrue(decoder.canDecode(forClass(String.class), MimeTypeUtils.TEXT_PLAIN)); |
||||
assertEquals(!textOnly, decoder.canDecode(forClass(String.class), MediaType.TEXT_EVENT_STREAM)); |
||||
} |
||||
|
||||
private void assertStringEncoder(Encoder<?> encoder, boolean textOnly) { |
||||
assertEquals(CharSequenceEncoder.class, encoder.getClass()); |
||||
assertTrue(encoder.canEncode(forClass(String.class), MimeTypeUtils.TEXT_PLAIN)); |
||||
assertEquals(!textOnly, encoder.canEncode(forClass(String.class), MediaType.TEXT_EVENT_STREAM)); |
||||
} |
||||
|
||||
private void assertSseReader(List<HttpMessageReader<?>> readers) { |
||||
HttpMessageReader<?> reader = readers.get(this.index.getAndIncrement()); |
||||
assertEquals(ServerSentEventHttpMessageReader.class, reader.getClass()); |
||||
Decoder<?> decoder = ((ServerSentEventHttpMessageReader) reader).getDecoder(); |
||||
assertNotNull(decoder); |
||||
assertEquals(Jackson2JsonDecoder.class, decoder.getClass()); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue