-
-
Notifications
You must be signed in to change notification settings - Fork 15.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split a JSON byte stream into JSON objects/arrays. Fixes #2536 #2547
Conversation
|
||
/** | ||
* Splits a byte stream of JSON objects and arrays into individual objects/arrays and passes them up the | ||
* channel pipeline. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use {@link ChannelPipeline}
@trustin wdyt ? |
@jakobbuchgraber I'm doing something a litte different in my project, maybe you like it: basically using a processor to find some json markers: private static class MarkerProcessor implements ByteBufProcessor {
private int marker = 0;
private int counter = 0;
private int depth = 0;
private byte open = '{';
private byte close = '}';
private byte stringMarker = '"';
private boolean inString = false;
@Override
public boolean process(byte value) throws Exception {
counter++;
if (value == stringMarker) {
inString = !inString;
}
if (!inString && value == open) {
depth++;
}
if (!inString && value == close) {
depth--;
if (depth == 0) {
marker = counter;
}
}
return true;
}
public int marker() {
return marker;
}
} I'm doing slightly different stuff but you can use the processor for this very efficiently. |
@daschl thanks for sharing. I started with a processor too (as I learned from @normanmaurer's FB talk :P ), but I also have to be able to look back one byte to check for escape characters (e.g. "foo " bar") and so I kinda felt the loop was nicer for my purposes. Maybe I should benchmark both versions, but I didn't bother with these kind of micro optimizations yet 😄 |
ch.writeInbound(Unpooled.copiedBuffer("blabla 123", CharsetUtil.UTF_8)); | ||
assertNull(ch.readInbound()); | ||
|
||
assertFalse(ch.finish()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could also check if an exception is raised here.
Could you also add a test case where a string contains '{' and other potentially confusing tokens? |
I also want to see an option that enables a streaming of a JSON array elements, whose size is potentially infinite. For example, when a client sends this: [
"a",
{ key: "value" },
"c",
...
] The decoder could generate a frame for each array element (i.e. ""a"", "{ key: "value" }", "c"", ...) |
I addressed the comments and I think it's ready for final review/merge. |
private final boolean streamArrayElements; | ||
|
||
public JsonObjectDecoder() { | ||
this(Integer.MAX_VALUE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default maxObjectLength
should be a much smaller value? 1048576?
Looks pretty good all in all. Left some comments for tiny things. To summarize:
|
done |
Motivation: See GitHub Issue netty#2536. Modifications: Introduce the class JsonObjectDecoder to split a JSON byte stream into individual JSON objets/arrays. Result: A Netty application can now handle a byte stream where multiple JSON documents follow eachother as opposed to only a single JSON document per request.
Nice work. Merged into 4.1 and master. 👍 |
It might be worth to add a comment that this implementation is only compatible with UTF-8 or ASCII encoded streams. Might event be worth it to add Charset as a constructor parameter and assert that it is UTF-8 straight away. This would make the API ready for possible future implementation of other encodings support. Same goes to LineBasedFrameDecoder and XmlFrameDecoder - both missing a comment explaining that they are expecting the stream in UTF-8. |
Are you interested in providing a PR?
… Am 12.12.2018 um 21:04 schrieb Alex Vasiliev ***@***.***>:
It might be worth to add a comment that this implementation is only compatible with UTF-8 or ASCII encoded streams. Might event be worth it to add Charset as a constructor parameter and assert that it is UTF-8 straight away. This would make the API ready for possible future implementation of other encodings support. Same goes to LineBasedFrameDecoder and XmlFrameDecoder - both missing a comment explaining that they are expecting the stream in UTF-8.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Let me give it a try. :) |
Motivation:
See GitHub Issue #2536.
Modifications:
Introduce the class JsonObjectDecoder to split a JSON byte stream
into individual JSON objets/arrays.
Result:
A Netty application can now handle a byte stream where multiple JSON
documents follow eachother as opposed to only a single JSON document
per request.
@trustin @daschl @normanmaurer please review :-)