Skip to content

Commit e276ec0

Browse files
committed
Added support for Readers and Writers
Signed-off-by: David Kral <[email protected]>
1 parent 7f6c7ad commit e276ec0

File tree

9 files changed

+510
-243
lines changed

9 files changed

+510
-243
lines changed

http/media/helidon-json/src/main/java/io/helidon/http/media/helidon/HelidonJsonReader.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.IOException;
44
import java.io.InputStream;
55
import java.io.InputStreamReader;
6+
import java.io.Reader;
67
import java.io.UncheckedIOException;
78
import java.nio.charset.Charset;
89
import java.util.Optional;
@@ -22,20 +23,22 @@ class HelidonJsonReader<T> implements EntityReader<T> {
2223

2324
@Override
2425
public T read(GenericType<T> type, InputStream stream, Headers headers) {
25-
InputStream inputStream = contentTypeCharset(headers)
26-
.map(charset -> new InputStreamReader(stream, charset))
27-
.map(reader -> (InputStream) new ReaderInputStream(reader))
28-
.orElse(stream);
29-
return read(type, inputStream);
26+
Optional<InputStreamReader> reader = contentTypeCharset(headers)
27+
.map(charset -> new InputStreamReader(stream, charset));
28+
if (reader.isPresent()) {
29+
return read(type, reader.get());
30+
}
31+
return read(type, stream);
3032
}
3133

3234
@Override
3335
public T read(GenericType<T> type, InputStream stream, Headers requestHeaders, Headers responseHeaders) {
34-
InputStream inputStream = contentTypeCharset(responseHeaders)
35-
.map(charset -> new InputStreamReader(stream, charset))
36-
.map(reader -> (InputStream) new ReaderInputStream(reader))
37-
.orElse(stream);
38-
return read(type, inputStream);
36+
Optional<InputStreamReader> reader = contentTypeCharset(responseHeaders)
37+
.map(charset -> new InputStreamReader(stream, charset));
38+
if (reader.isPresent()) {
39+
return read(type, reader.get());
40+
}
41+
return read(type, stream);
3942
}
4043

4144
private T read(GenericType<T> type, InputStream in) {
@@ -46,6 +49,14 @@ private T read(GenericType<T> type, InputStream in) {
4649
}
4750
}
4851

52+
private T read(GenericType<T> type, Reader reader) {
53+
try (reader) {
54+
return jsonBinding.deserialize(reader, type);
55+
} catch (IOException e) {
56+
throw new UncheckedIOException(e);
57+
}
58+
}
59+
4960
private Optional<Charset> contentTypeCharset(Headers headers) {
5061
return headers.contentType()
5162
.flatMap(HttpMediaType::charset)

http/media/helidon-json/src/main/java/io/helidon/http/media/helidon/HelidonJsonWriter.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22

33
import java.io.IOException;
44
import java.io.OutputStream;
5+
import java.io.OutputStreamWriter;
56
import java.io.UncheckedIOException;
7+
import java.io.Writer;
8+
import java.nio.charset.Charset;
9+
import java.util.Optional;
610

711
import io.helidon.common.GenericType;
12+
import io.helidon.common.media.type.MediaTypes;
813
import io.helidon.http.HeaderValues;
914
import io.helidon.http.Headers;
15+
import io.helidon.http.HttpMediaType;
1016
import io.helidon.http.WritableHeaders;
1117
import io.helidon.http.media.EntityWriter;
1218
import io.helidon.json.binding.JsonBinding;
@@ -26,6 +32,20 @@ public void write(GenericType<T> type,
2632
Headers requestHeaders,
2733
WritableHeaders<?> responseHeaders) {
2834
responseHeaders.setIfAbsent(HeaderValues.CONTENT_TYPE_JSON);
35+
36+
for (HttpMediaType acceptedType : requestHeaders.acceptedTypes()) {
37+
if (acceptedType.test(MediaTypes.APPLICATION_JSON)) {
38+
Optional<String> charset = acceptedType.charset();
39+
if (charset.isPresent()) {
40+
Charset characterSet = Charset.forName(charset.get());
41+
write(type, object, new OutputStreamWriter(outputStream, characterSet));
42+
} else {
43+
write(type, object, outputStream);
44+
}
45+
return;
46+
}
47+
}
48+
2949
write(type, object, outputStream);
3050
}
3151

@@ -35,6 +55,14 @@ public void write(GenericType<T> type, T object, OutputStream outputStream, Writ
3555
write(type, object, outputStream);
3656
}
3757

58+
private void write(GenericType<T> type, T object, Writer out) {
59+
try (out) {
60+
jsonBinding.serialize(out, object, type);
61+
} catch (IOException e) {
62+
throw new UncheckedIOException(e);
63+
}
64+
}
65+
3866
private void write(GenericType<T> type, T object, OutputStream out) {
3967
try (out) {
4068
jsonBinding.serialize(out, object, type);

json/binding/src/main/java/io/helidon/json/binding/JsonBinding.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.io.InputStream;
44
import java.io.OutputStream;
5+
import java.io.Reader;
6+
import java.io.Writer;
57
import java.util.HashSet;
68
import java.util.Set;
79
import java.util.function.Consumer;
@@ -54,6 +56,12 @@ static JsonBinding create(Consumer<JsonBindingConfig.Builder> consumer) {
5456

5557
<T> void serialize(OutputStream outputStream, T obj, GenericType<? super T> type);
5658

59+
void serialize(Writer writer, Object obj);
60+
61+
<T> void serialize(Writer writer, T obj, Class<? super T> type);
62+
63+
<T> void serialize(Writer writer, T obj, GenericType<? super T> type);
64+
5765
<T> T deserialize(byte[] bytes, Class<T> type);
5866

5967
<T> T deserialize(byte[] bytes, GenericType<T> type);
@@ -66,6 +74,10 @@ static JsonBinding create(Consumer<JsonBindingConfig.Builder> consumer) {
6674

6775
<T> T deserialize(InputStream inputStream, GenericType<T> type);
6876

77+
<T> T deserialize(Reader reader, Class<T> type);
78+
79+
<T> T deserialize(Reader reader, GenericType<T> type);
80+
6981
<T> T deserialize(JsonValue jsonValue, Class<T> type);
7082

7183
<T> T deserialize(JsonValue jsonValue, GenericType<T> type);

json/binding/src/main/java/io/helidon/json/binding/JsonBindingImpl.java

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.io.IOException;
55
import java.io.InputStream;
66
import java.io.OutputStream;
7+
import java.io.Reader;
8+
import java.io.Writer;
79
import java.lang.reflect.Array;
810
import java.lang.reflect.Type;
911
import java.nio.charset.StandardCharsets;
@@ -23,6 +25,7 @@
2325
final class JsonBindingImpl implements JsonBinding, JsonBindingConfigurator {
2426

2527
public static final byte[] NULL_BYTES = "null".getBytes(StandardCharsets.UTF_8);
28+
public static final char[] NULL_CHARS = "null".toCharArray();
2629
private final ThreadLocal<CachedParser> parserCache = ThreadLocal.withInitial(CachedParser::new);
2730
private final ThreadLocal<CachedStreamParser> parserStreamCache = ThreadLocal.withInitial(CachedStreamParser::new);
2831

@@ -128,7 +131,7 @@ public <T> String serialize(T obj, GenericType<? super T> type) {
128131
@SuppressWarnings("unchecked")
129132
public void serialize(OutputStream outputStream, Object obj) {
130133
if (obj == null) {
131-
try {
134+
try (outputStream) {
132135
outputStream.write(NULL_BYTES);
133136
return;
134137
} catch (IOException e) {
@@ -148,7 +151,7 @@ public void serialize(OutputStream outputStream, Object obj) {
148151
@Override
149152
public <T> void serialize(OutputStream outputStream, T obj, Class<? super T> type) {
150153
if (obj == null) {
151-
try {
154+
try (outputStream) {
152155
outputStream.write(NULL_BYTES);
153156
return;
154157
} catch (IOException e) {
@@ -168,7 +171,7 @@ public <T> void serialize(OutputStream outputStream, T obj, Class<? super T> typ
168171
@Override
169172
public <T> void serialize(OutputStream outputStream, T obj, GenericType<? super T> type) {
170173
if (obj == null) {
171-
try {
174+
try (outputStream) {
172175
outputStream.write(NULL_BYTES);
173176
return;
174177
} catch (IOException e) {
@@ -185,6 +188,67 @@ public <T> void serialize(OutputStream outputStream, T obj, GenericType<? super
185188
}
186189
}
187190

191+
@Override
192+
@SuppressWarnings("unchecked")
193+
public void serialize(Writer writer, Object obj) {
194+
if (obj == null) {
195+
try (writer) {
196+
writer.write(NULL_CHARS);
197+
return;
198+
} catch (IOException e) {
199+
throw new RuntimeException(e);
200+
}
201+
}
202+
try (Generator generator = Generator.create(writer)) {
203+
JsonSerializer<Object> converter = (JsonSerializer<Object>) getSerializer(obj.getClass());
204+
converter.serialize(generator, obj, true);
205+
} catch (RuntimeException e) {
206+
throw e;
207+
} catch (Exception e) {
208+
throw new RuntimeException(e);
209+
}
210+
}
211+
212+
@Override
213+
public <T> void serialize(Writer writer, T obj, Class<? super T> type) {
214+
if (obj == null) {
215+
try (writer) {
216+
writer.write(NULL_CHARS);
217+
return;
218+
} catch (IOException e) {
219+
throw new RuntimeException(e);
220+
}
221+
}
222+
try (Generator generator = Generator.create(writer)) {
223+
JsonSerializer<? super T> converter = getSerializer(type);
224+
converter.serialize(generator, obj, true);
225+
} catch (RuntimeException e) {
226+
throw e;
227+
} catch (Exception e) {
228+
throw new RuntimeException(e);
229+
}
230+
}
231+
232+
@Override
233+
public <T> void serialize(Writer writer, T obj, GenericType<? super T> type) {
234+
if (obj == null) {
235+
try (writer) {
236+
writer.write(NULL_CHARS);
237+
return;
238+
} catch (IOException e) {
239+
throw new RuntimeException(e);
240+
}
241+
}
242+
try (Generator generator = Generator.create(writer)) {
243+
JsonSerializer<? super T> converter = getSerializer(type);
244+
converter.serialize(generator, obj, true);
245+
} catch (RuntimeException e) {
246+
throw e;
247+
} catch (Exception e) {
248+
throw new RuntimeException(e);
249+
}
250+
}
251+
188252
@Override
189253
public <T> T deserialize(byte[] bytes, Class<T> type) {
190254
JsonDeserializer<T> deserializer = getDeserializer(type);
@@ -243,6 +307,16 @@ public <T> T deserialize(InputStream inputStream, GenericType<T> type) {
243307
return deserialized;
244308
}
245309

310+
@Override
311+
public <T> T deserialize(Reader reader, Class<T> type) {
312+
return deserialize(new ReaderInputStream(reader), type);
313+
}
314+
315+
@Override
316+
public <T> T deserialize(Reader reader, GenericType<T> type) {
317+
return deserialize(new ReaderInputStream(reader), type);
318+
}
319+
246320
@Override
247321
public <T> T deserialize(JsonValue jsonValue, Class<T> type) {
248322
JsonDeserializer<T> deserializer = getDeserializer(type);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.helidon.http.media.helidon;
1+
package io.helidon.json.binding;
22

33
import java.io.IOException;
44
import java.io.InputStream;

0 commit comments

Comments
 (0)