java语言下,进行json处理的工具类jackson, fastjson, gson等,使用起来比较简单,就不介绍了,这次我们就来探索一下其中gson的具体实现,其核心处理类为JsonReader和JsonWriter进行json格式数据的读取和写入,上层TypeAdapter使用其进行json和具体数据类型的转换,而Gson调用时会根据类型获取到具体的TypeAdapter进行使用
在将json字符串转换成Java对象时,首先需要有定义Java的类,这里我们先不定义,而是使用一种更通用的,将json字符串转换成JsonElement的方法(com.google.gson.JsonParser#parseString
)实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public static JsonElement parseReader(JsonReader reader) throws JsonIOException, JsonSyntaxException { boolean lenient = reader.isLenient(); reader.setLenient(true); try { return Streams.parse(reader); } catch (StackOverflowError e) { throw new JsonParseException("Failed parsing JSON source: " + reader + " to Json", e); } catch (OutOfMemoryError e) { throw new JsonParseException("Failed parsing JSON source: " + reader + " to Json", e); } finally { reader.setLenient(lenient); } }
public static JsonElement parse(JsonReader reader) throws JsonParseException { boolean isEmpty = true; try { reader.peek(); isEmpty = false; return TypeAdapters.JSON_ELEMENT.read(reader); } catch (EOFException e) { if (isEmpty) { return JsonNull.INSTANCE; } throw new JsonSyntaxException(e); } catch (MalformedJsonException e) { throw new JsonSyntaxException(e); } catch (IOException e) { throw new JsonIOException(e); } catch (NumberFormatException e) { throw new JsonSyntaxException(e); } }
|
最终调用如下Adapter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
private JsonElement tryBeginNesting(JsonReader in, JsonToken peeked) throws IOException { switch (peeked) { case BEGIN_ARRAY: in.beginArray(); return new JsonArray(); case BEGIN_OBJECT: in.beginObject(); return new JsonObject(); default: return null; } }
private JsonElement readTerminal(JsonReader in, JsonToken peeked) throws IOException { switch (peeked) { case STRING: return new JsonPrimitive(in.nextString()); case NUMBER: String number = in.nextString(); return new JsonPrimitive(new LazilyParsedNumber(number)); case BOOLEAN: return new JsonPrimitive(in.nextBoolean()); case NULL: in.nextNull(); return JsonNull.INSTANCE; default: throw new IllegalStateException("Unexpected token: " + peeked); } }
@Override public JsonElement read(JsonReader in) throws IOException { if (in instanceof JsonTreeReader) { return ((JsonTreeReader) in).nextJsonElement(); }
JsonElement current; JsonToken peeked = in.peek();
current = tryBeginNesting(in, peeked); if (current == null) { return readTerminal(in, peeked); }
Deque<JsonElement> stack = new ArrayDeque<>();
while (true) { while (in.hasNext()) { String name = null; if (current instanceof JsonObject) { name = in.nextName(); }
peeked = in.peek(); JsonElement value = tryBeginNesting(in, peeked); boolean isNesting = value != null;
if (value == null) { value = readTerminal(in, peeked); }
if (current instanceof JsonArray) { ((JsonArray) current).add(value); } else { ((JsonObject) current).add(name, value); }
if (isNesting) { stack.addLast(current); current = value; } }
if (current instanceof JsonArray) { in.endArray(); } else { in.endObject(); }
if (stack.isEmpty()) { return current; } else { current = stack.removeLast(); } } }
@Override public void write(JsonWriter out, JsonElement value) throws IOException { } };
|