Finally it seams no JSON parser in java suit for my situation.
I am using netty to build a network application. for nio, when there is data coming from network, the decode method in ByteToMessageDecoder is called.
In this method I need to find out JSON block from ByteBuf.
Since there is no available JSON parser, I wrote a method to split the JSON Block from ByteBuf.
public static void extractJsonBlocks(ByteBuf buf, List<Object> out) throws UnsupportedEncodingException {
// the total bytes that can read from ByteBuf
int readable = buf.readableBytes();
int bracketDepth = 0;
// when found a json block, this value will be set
int offset = 0;
// whether current character is in a string value
boolean inStr = false;
// a temporary bytes buf for store json block
byte[] data = new byte[readable];
// loop all the coming data
for (int i = 0; i < readable; i++) {
// read from ByteBuf
byte b = buf.readByte();
// put it in the buffer, be care of the offset
data[i - offset] = b;
if (b == SYM_L_BRACKET && !inStr) {
// if it a left bracket and not in a string value
bracketDepth++;
} else if (b == SYM_R_BRACKET && !inStr) {
// if it a right bracket and not in a string value
if (bracketDepth == 1) {
// if current bracket depth is 1, means found a whole json block
out.add(new String(data, "utf-8").trim());
// create a new buffer
data = new byte[readable - offset];
// update the offset
offset = i;
// reset the bracket depth
bracketDepth = 0;
} else {
bracketDepth--;
}
} else if (b == SYM_QUOTE) {
// when find a quote, we need see whether preview character is escape.
byte prev = i == 0 ? 0 : data[i - 1 - offset];
if (prev != SYM_ESCAPE) {
inStr = !inStr;
}
}
}
// finally there may still be some data left in the ByteBuf, that can not form a json block, they should be used to combine with the following datas
// so we need to reset the reader index to the first byte of the left data
// and discard the data used for json blocks
buf.readerIndex(offset == 0 ? offset : offset + 1);
buf.discardReadBytes();
}
maybe this is a not perfect parser, but it works well for my application now.