Skip to content

Commit 9f8c29a

Browse files
committed
Remove dependency on web classes from new Encoder/Decoder implementation
The web dependency still need to be there since it appears that spring-rsocket requires it
1 parent 498a52e commit 9f8c29a

File tree

2 files changed

+80
-13
lines changed

2 files changed

+80
-13
lines changed

Diff for: spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonDecoder.java

+60-10
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,35 @@
1616

1717
package org.springframework.cloud.function.rsocket;
1818

19+
import java.io.ByteArrayOutputStream;
20+
import java.io.IOException;
21+
import java.io.InputStream;
22+
import java.io.OutputStream;
1923
import java.lang.reflect.Type;
2024
import java.util.Map;
2125

26+
import org.reactivestreams.Publisher;
2227
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
2328
import org.springframework.cloud.function.json.JsonMapper;
2429
import org.springframework.core.ResolvableType;
30+
import org.springframework.core.codec.AbstractDecoder;
2531
import org.springframework.core.codec.DecodingException;
2632
import org.springframework.core.io.buffer.DataBuffer;
27-
import org.springframework.http.codec.json.Jackson2JsonDecoder;
33+
import org.springframework.core.io.buffer.DataBufferUtils;
2834
import org.springframework.lang.Nullable;
2935
import org.springframework.messaging.support.MessageBuilder;
3036
import org.springframework.util.MimeType;
3137
import org.springframework.util.MimeTypeUtils;
3238

39+
import reactor.core.publisher.Flux;
40+
3341
/**
3442
*
3543
* @author Oleg Zhurakousky
3644
* @since 3.1
3745
*
3846
*/
39-
class MessageAwareJsonDecoder extends Jackson2JsonDecoder {
47+
class MessageAwareJsonDecoder extends AbstractDecoder<Object> {
4048

4149
private final JsonMapper jsonMapper;
4250

@@ -49,22 +57,25 @@ public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType
4957
return mimeType.isCompatibleWith(MimeTypeUtils.APPLICATION_JSON);
5058
}
5159

52-
5360
@SuppressWarnings("unchecked")
5461
@Override
5562
public Object decode(DataBuffer dataBuffer, ResolvableType targetType,
56-
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) throws DecodingException {
63+
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints)
64+
throws DecodingException {
5765

58-
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, String.class, Object.class);
59-
Map<String, Object> messageMap = (Map<String, Object>) super.decode(dataBuffer, type, mimeType, hints);
66+
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, String.class,
67+
Object.class);
68+
Map<String, Object> messageMap = (Map<String, Object>) doDecode(dataBuffer, type,
69+
mimeType, hints);
6070
if (messageMap.containsKey(FunctionRSocketUtils.PAYLOAD)) {
6171
Type requestedType = FunctionTypeUtils.getGenericType(targetType.getType());
62-
Object payload = this.jsonMapper.fromJson(messageMap.get(FunctionRSocketUtils.PAYLOAD), requestedType);
72+
Object payload = this.jsonMapper.fromJson(
73+
messageMap.get(FunctionRSocketUtils.PAYLOAD), requestedType);
6374

6475
if (FunctionTypeUtils.isMessage(targetType.getType())) {
65-
return MessageBuilder.withPayload(payload)
66-
.copyHeaders((Map<String, ?>) messageMap.get(FunctionRSocketUtils.HEADERS))
67-
.build();
76+
return MessageBuilder.withPayload(payload).copyHeaders(
77+
(Map<String, ?>) messageMap.get(FunctionRSocketUtils.HEADERS))
78+
.build();
6879
}
6980
else {
7081
return payload;
@@ -73,6 +84,45 @@ public Object decode(DataBuffer dataBuffer, ResolvableType targetType,
7384
else {
7485
return messageMap;
7586
}
87+
}
88+
89+
private Object doDecode(DataBuffer dataBuffer, ResolvableType targetType,
90+
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints)
91+
throws DecodingException {
92+
93+
try {
94+
byte[] data = toByteArray(dataBuffer.asInputStream());
95+
return this.jsonMapper.fromJson(data, targetType.getType());
96+
}
97+
catch (IOException ex) {
98+
throw new IllegalStateException(ex);
99+
}
100+
finally {
101+
DataBufferUtils.release(dataBuffer);
102+
}
103+
}
104+
105+
private byte[] toByteArray(final InputStream input) throws IOException {
106+
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
107+
copyLarge(input, output, new byte[2048]);
108+
return output.toByteArray();
109+
}
110+
}
76111

112+
private long copyLarge(final InputStream input, final OutputStream output,
113+
final byte[] buffer) throws IOException {
114+
long count = 0;
115+
int n;
116+
while (-1 != (n = input.read(buffer))) {
117+
output.write(buffer, 0, n);
118+
count += n;
119+
}
120+
return count;
121+
}
122+
123+
@Override
124+
public Flux<Object> decode(Publisher<DataBuffer> inputStream,
125+
ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
126+
return Flux.from(inputStream).map(buffer -> decode(buffer, elementType, mimeType, hints));
77127
}
78128
}

Diff for: spring-cloud-function-rsocket/src/main/java/org/springframework/cloud/function/rsocket/MessageAwareJsonEncoder.java

+20-3
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,44 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import org.reactivestreams.Publisher;
2324
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
2425
import org.springframework.cloud.function.json.JsonMapper;
2526
import org.springframework.core.ResolvableType;
27+
import org.springframework.core.codec.AbstractEncoder;
28+
import org.springframework.core.codec.ByteArrayEncoder;
2629
import org.springframework.core.io.buffer.DataBuffer;
2730
import org.springframework.core.io.buffer.DataBufferFactory;
28-
import org.springframework.http.codec.json.Jackson2JsonEncoder;
2931
import org.springframework.lang.Nullable;
3032
import org.springframework.messaging.Message;
3133
import org.springframework.util.MimeType;
3234
import org.springframework.util.MimeTypeUtils;
3335

36+
import reactor.core.publisher.Flux;
37+
3438
/**
3539
*
40+
* An extended implementation
3641
* @author Oleg Zhurakousky
3742
* @since 3.1
3843
*
3944
*/
40-
class MessageAwareJsonEncoder extends Jackson2JsonEncoder {
45+
class MessageAwareJsonEncoder extends AbstractEncoder<Object> {
4146

4247
private final JsonMapper mapper;
4348

4449
private final boolean isClient;
4550

51+
private final ByteArrayEncoder byteArrayEncoder;
52+
4653
MessageAwareJsonEncoder(JsonMapper mapper) {
4754
this(mapper, false);
4855
}
4956

5057
MessageAwareJsonEncoder(JsonMapper mapper, boolean isClient) {
5158
this.mapper = mapper;
5259
this.isClient = isClient;
60+
this.byteArrayEncoder = new ByteArrayEncoder();
5361
}
5462

5563
@Override
@@ -81,6 +89,15 @@ else if (!(value instanceof Map)) {
8189
}
8290
value = Collections.singletonMap(FunctionRSocketUtils.PAYLOAD, value);
8391
}
84-
return super.encodeValue(value, bufferFactory, valueType, mimeType, hints);
92+
byte[] data = this.mapper.toJson(value);
93+
return this.byteArrayEncoder.encodeValue(data, bufferFactory, valueType, mimeType, hints);
94+
}
95+
96+
@Override
97+
public Flux<DataBuffer> encode(Publisher<? extends Object> inputStream,
98+
DataBufferFactory bufferFactory, ResolvableType elementType,
99+
MimeType mimeType, Map<String, Object> hints) {
100+
return Flux.from(inputStream).map(value ->
101+
encodeValue(value, bufferFactory, elementType, mimeType, hints));
85102
}
86103
}

0 commit comments

Comments
 (0)