Skip to content

Commit 88c5f59

Browse files
committed
Added DataBuffer Encoder/Decoder
This commit adds a DataBuffer Encoder and Decoder, and uses it in the annotation-based processing model. Note that these codecs are not used in the functional processing model, since the BodyInserter/BodyExtractor already have methods for writing/reading DataBuffers. Issue: SPR-15148
1 parent 141e04a commit 88c5f59

File tree

8 files changed

+263
-10
lines changed

8 files changed

+263
-10
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.core.codec;
18+
19+
import java.util.Map;
20+
21+
import org.reactivestreams.Publisher;
22+
import reactor.core.publisher.Flux;
23+
24+
import org.springframework.core.ResolvableType;
25+
import org.springframework.core.io.buffer.DataBuffer;
26+
import org.springframework.util.MimeType;
27+
import org.springframework.util.MimeTypeUtils;
28+
29+
/**
30+
* Simple pass-through decoder for {@link DataBuffer}s.
31+
* <p><strong>Note</strong> that the "decoded" buffers returned by instances of this class should
32+
* be released after usage by calling
33+
* {@link org.springframework.core.io.buffer.DataBufferUtils#release(DataBuffer)}.
34+
*
35+
* @author Arjen Poutsma
36+
* @since 5.0
37+
*/
38+
public class DataBufferDecoder extends AbstractDecoder<DataBuffer> {
39+
40+
public DataBufferDecoder() {
41+
super(MimeTypeUtils.ALL);
42+
}
43+
44+
45+
@Override
46+
public boolean canDecode(ResolvableType elementType, MimeType mimeType) {
47+
Class<?> clazz = elementType.getRawClass();
48+
return (super.canDecode(elementType, mimeType) && DataBuffer.class.isAssignableFrom(clazz));
49+
}
50+
51+
@Override
52+
public Flux<DataBuffer> decode(Publisher<DataBuffer> inputStream, ResolvableType elementType,
53+
MimeType mimeType, Map<String, Object> hints) {
54+
return Flux.from(inputStream);
55+
}
56+
57+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.core.codec;
18+
19+
import java.util.Map;
20+
21+
import org.reactivestreams.Publisher;
22+
import reactor.core.publisher.Flux;
23+
24+
import org.springframework.core.ResolvableType;
25+
import org.springframework.core.io.buffer.DataBuffer;
26+
import org.springframework.core.io.buffer.DataBufferFactory;
27+
import org.springframework.util.MimeType;
28+
import org.springframework.util.MimeTypeUtils;
29+
30+
/**
31+
* Simple pass-through encoder for {@link DataBuffer}s.
32+
*
33+
* @author Arjen Poutsma
34+
* @since 5.0
35+
*/
36+
public class DataBufferEncoder extends AbstractEncoder<DataBuffer> {
37+
38+
public DataBufferEncoder() {
39+
super(MimeTypeUtils.ALL);
40+
}
41+
42+
43+
@Override
44+
public boolean canEncode(ResolvableType elementType, MimeType mimeType) {
45+
Class<?> clazz = elementType.getRawClass();
46+
return (super.canEncode(elementType, mimeType) && DataBuffer.class.isAssignableFrom(clazz));
47+
}
48+
49+
@Override
50+
public Flux<DataBuffer> encode(Publisher<? extends DataBuffer> inputStream,
51+
DataBufferFactory bufferFactory, ResolvableType elementType, MimeType mimeType,
52+
Map<String, Object> hints) {
53+
54+
return Flux.from(inputStream);
55+
}
56+
57+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.core.codec;
18+
19+
import java.nio.ByteBuffer;
20+
import java.util.Collections;
21+
22+
import org.junit.Test;
23+
import org.reactivestreams.Publisher;
24+
import reactor.core.publisher.Flux;
25+
26+
import org.springframework.core.ResolvableType;
27+
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
28+
import org.springframework.core.io.buffer.DataBuffer;
29+
import org.springframework.util.MimeTypeUtils;
30+
31+
import static org.junit.Assert.assertFalse;
32+
import static org.junit.Assert.assertSame;
33+
import static org.junit.Assert.assertTrue;
34+
35+
/**
36+
* @author Sebastien Deleuze
37+
*/
38+
public class DataBufferDecoderTests extends AbstractDataBufferAllocatingTestCase {
39+
40+
private final DataBufferDecoder decoder = new DataBufferDecoder();
41+
42+
@Test
43+
public void canDecode() {
44+
assertTrue(this.decoder.canDecode(ResolvableType.forClass(DataBuffer.class),
45+
MimeTypeUtils.TEXT_PLAIN));
46+
assertFalse(this.decoder.canDecode(ResolvableType.forClass(Integer.class),
47+
MimeTypeUtils.TEXT_PLAIN));
48+
assertTrue(this.decoder.canDecode(ResolvableType.forClass(DataBuffer.class),
49+
MimeTypeUtils.APPLICATION_JSON));
50+
}
51+
52+
@Test
53+
public void decode() {
54+
DataBuffer fooBuffer = stringBuffer("foo");
55+
DataBuffer barBuffer = stringBuffer("bar");
56+
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
57+
Flux<DataBuffer> output = this.decoder.decode(source,
58+
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
59+
null, Collections.emptyMap());
60+
61+
assertSame(source, output);
62+
}
63+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.core.codec;
18+
19+
import java.nio.ByteBuffer;
20+
import java.util.Collections;
21+
22+
import org.junit.Test;
23+
import org.reactivestreams.Publisher;
24+
import reactor.core.publisher.Flux;
25+
26+
import org.springframework.core.ResolvableType;
27+
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
28+
import org.springframework.core.io.buffer.DataBuffer;
29+
import org.springframework.util.MimeTypeUtils;
30+
31+
import static org.junit.Assert.assertFalse;
32+
import static org.junit.Assert.assertSame;
33+
import static org.junit.Assert.assertTrue;
34+
35+
/**
36+
* @author Sebastien Deleuze
37+
*/
38+
public class DataBufferEncoderTests extends AbstractDataBufferAllocatingTestCase {
39+
40+
private final DataBufferEncoder encoder = new DataBufferEncoder();
41+
42+
@Test
43+
public void canEncode() {
44+
assertTrue(this.encoder.canEncode(ResolvableType.forClass(DataBuffer.class),
45+
MimeTypeUtils.TEXT_PLAIN));
46+
assertFalse(this.encoder.canEncode(ResolvableType.forClass(Integer.class),
47+
MimeTypeUtils.TEXT_PLAIN));
48+
assertTrue(this.encoder.canEncode(ResolvableType.forClass(DataBuffer.class),
49+
MimeTypeUtils.APPLICATION_JSON));
50+
}
51+
52+
@Test
53+
public void encode() {
54+
DataBuffer fooBuffer = stringBuffer("foo");
55+
DataBuffer barBuffer = stringBuffer("bar");
56+
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
57+
58+
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory,
59+
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
60+
null, Collections.emptyMap());
61+
62+
assertSame(source, output);
63+
}
64+
65+
}

spring-web-reactive/src/main/java/org/springframework/web/reactive/config/WebReactiveConfigurationSupport.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,8 @@
3434
import org.springframework.core.codec.ByteBufferDecoder;
3535
import org.springframework.core.codec.ByteBufferEncoder;
3636
import org.springframework.core.codec.CharSequenceEncoder;
37+
import org.springframework.core.codec.DataBufferDecoder;
38+
import org.springframework.core.codec.DataBufferEncoder;
3739
import org.springframework.core.codec.Encoder;
3840
import org.springframework.core.codec.ResourceDecoder;
3941
import org.springframework.core.codec.StringDecoder;
@@ -328,6 +330,7 @@ protected void configureMessageReaders(List<HttpMessageReader<?>> messageReaders
328330
protected final void addDefaultHttpMessageReaders(List<HttpMessageReader<?>> readers) {
329331
readers.add(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
330332
readers.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
333+
readers.add(new DecoderHttpMessageReader<>(new DataBufferDecoder()));
331334
readers.add(new DecoderHttpMessageReader<>(new StringDecoder()));
332335
readers.add(new DecoderHttpMessageReader<>(new ResourceDecoder()));
333336
if (jaxb2Present) {
@@ -476,6 +479,7 @@ protected final void addDefaultHttpMessageWriters(List<HttpMessageWriter<?>> wri
476479
List<Encoder<?>> sseDataEncoders = new ArrayList<>();
477480
writers.add(new EncoderHttpMessageWriter<>(new ByteArrayEncoder()));
478481
writers.add(new EncoderHttpMessageWriter<>(new ByteBufferEncoder()));
482+
writers.add(new EncoderHttpMessageWriter<>(new DataBufferEncoder()));
479483
writers.add(new EncoderHttpMessageWriter<>(new CharSequenceEncoder()));
480484
writers.add(new ResourceHttpMessageWriter());
481485
if (jaxb2Present) {

spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@
3737
import org.springframework.core.annotation.AnnotationUtils;
3838
import org.springframework.core.codec.ByteArrayDecoder;
3939
import org.springframework.core.codec.ByteBufferDecoder;
40+
import org.springframework.core.codec.DataBufferDecoder;
4041
import org.springframework.core.codec.StringDecoder;
4142
import org.springframework.http.codec.DecoderHttpMessageReader;
4243
import org.springframework.http.codec.HttpMessageReader;
@@ -96,6 +97,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
9697
public RequestMappingHandlerAdapter() {
9798
this.messageReaders.add(new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
9899
this.messageReaders.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
100+
this.messageReaders.add(new DecoderHttpMessageReader<>(new DataBufferDecoder()));
99101
this.messageReaders.add(new DecoderHttpMessageReader<>(new StringDecoder()));
100102
}
101103

spring-web-reactive/src/test/java/org/springframework/web/reactive/config/DelegatingWebReactiveConfigurationTests.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -37,8 +37,13 @@
3737
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
3838
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
3939

40-
import static org.junit.Assert.*;
41-
import static org.mockito.BDDMockito.*;
40+
import static org.junit.Assert.assertEquals;
41+
import static org.junit.Assert.assertSame;
42+
import static org.junit.Assert.assertTrue;
43+
import static org.mockito.BDDMockito.any;
44+
import static org.mockito.BDDMockito.doAnswer;
45+
import static org.mockito.BDDMockito.given;
46+
import static org.mockito.BDDMockito.verify;
4247

4348
/**
4449
* Test fixture for {@link DelegatingWebReactiveConfiguration} tests.
@@ -99,7 +104,7 @@ public void requestMappingHandlerAdapter() throws Exception {
99104
verify(webReactiveConfigurer).addArgumentResolvers(any());
100105

101106
assertSame(formatterRegistry.getValue(), initializerConversionService);
102-
assertEquals(6, readers.getValue().size());
107+
assertEquals(7, readers.getValue().size());
103108
}
104109

105110
@Test

spring-web-reactive/src/test/java/org/springframework/web/reactive/config/WebReactiveConfigurationSupportTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -139,7 +139,7 @@ public void requestMappingHandlerAdapter() throws Exception {
139139
assertNotNull(adapter);
140140

141141
List<HttpMessageReader<?>> readers = adapter.getMessageReaders();
142-
assertEquals(6, readers.size());
142+
assertEquals(7, readers.size());
143143

144144
assertHasMessageReader(readers, byte[].class, APPLICATION_OCTET_STREAM);
145145
assertHasMessageReader(readers, ByteBuffer.class, APPLICATION_OCTET_STREAM);
@@ -189,7 +189,7 @@ public void responseEntityResultHandler() throws Exception {
189189
assertEquals(0, handler.getOrder());
190190

191191
List<HttpMessageWriter<?>> writers = handler.getMessageWriters();
192-
assertEquals(7, writers.size());
192+
assertEquals(8, writers.size());
193193

194194
assertHasMessageWriter(writers, byte[].class, APPLICATION_OCTET_STREAM);
195195
assertHasMessageWriter(writers, ByteBuffer.class, APPLICATION_OCTET_STREAM);
@@ -215,7 +215,7 @@ public void responseBodyResultHandler() throws Exception {
215215
assertEquals(100, handler.getOrder());
216216

217217
List<HttpMessageWriter<?>> writers = handler.getMessageWriters();
218-
assertEquals(7, writers.size());
218+
assertEquals(8, writers.size());
219219

220220
assertHasMessageWriter(writers, byte[].class, APPLICATION_OCTET_STREAM);
221221
assertHasMessageWriter(writers, ByteBuffer.class, APPLICATION_OCTET_STREAM);

0 commit comments

Comments
 (0)