栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Json解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Json解析

1.通过词法分析将json解析成token序列

有如下json 

{ "key" : "value" , } 通过词法解析将得到一组token { key : value , }   罗列一下 JSON 所规定的数据类型:
  • BEGIN_OBJECT({)
  • END_OBJECT(})
  • BEGIN_ARRAY([)
  • END_ARRAY(])
  • NULL(null)
  • NUMBER(数字)
  • STRING(字符串)
  • BOOLEAN(true/false)
  • SEP_COLON(:)
  • SEP_COMMA(,) 
定义一个枚举类 来表示上面的数据类型,如下:
public enum TokenType {
 BEGIN_OBJECT(1), 
 END_OBJECT(2),
 BEGIN_ARRAY(4),
 END_ARRAY(8),
 NULL(16), 
 NUMBER(32), 
 STRING(64), 
 BOOLEAN(128), 
 SEP_COLON(256),
 SEP_COMMA(512),
 END_DOCUMENT(1024);
 TokenType(int code) { 
   this.code = code; 
 }
 private int code; 
 public int getTokenCode(){
  return code;
 } 
} 

使用token表示词类型和字面量

public class Token { 
    private TokenType tokenType;
    private String value; // 省略不重要的代码 
}

 遍历json字符将json串读取成一个token序列

2. 使用token序列进行语法分析

 根据json的构词规则对token序列进行语法分析,检验token序列是否符合json的规则,如不符合则抛出异常,如符合规则便可以对token序列进行遍历进行输出了,通过解析输出jsonObject或者jsonArray

private JsonObject parseJsonObject() {
        JsonObject jsonObject = new JsonObject();
        int expectToken = STRING_TOKEN | END_OBJECT_TOKEN;
        String key = null;
        Object value = null;
        while (tokens.hasMore()) {
            Token token = tokens.next();
            1234567
            TokenType tokenType = token.getTokenType();
            String tokenValue = token.getValue();
            switch (tokenType) {
                case BEGIN_OBJECT:
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key, parseJsonObject()); // 递归解析 jsonobject
                    expectToken = SEP_COMMA_TOKEN | END_OBJECT_TOKEN;
                    break;
                case END_OBJECT:
                    checkExpectToken(tokenType, expectToken);
                    return jsonObject;
                case BEGIN_ARRAY: // 解析 json array 
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key, parseJsonArray());
                    expectToken = SEP_COMMA_TOKEN | END_OBJECT_TOKEN;
                    break;
                case NULL:
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key, null);
                    expectToken = SEP_COMMA_TOKEN | END_OBJECT_TOKEN;
                    break;
                case NUMBER:
                    checkExpectToken(tokenType, expectToken);
                    if (tokenValue.contains(".") || tokenValue.contains("e") || tokenValue.contains("E")) {
                        jsonObject.put(key, Double.valueOf(tokenValue));
                    } else {
                        Long num = Long.valueOf(tokenValue);
                        if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) {
                            jsonObject.put(key, num);
                        } else {
                            jsonObject.put(key, num.intValue());
                        }
                    }
                    expectToken = SEP_COMMA_TOKEN | END_OBJECT_TOKEN;
                    break;
                case BOOLEAN:
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key, Boolean.valueOf(token.getValue()));
                    expectToken = SEP_COMMA_TOKEN | END_OBJECT_TOKEN;
                    break;
                case STRING:
                    checkExpectToken(tokenType, expectToken);
                    Token preToken = tokens.peekPrevious(); if (preToken.getTokenType() == TokenType.SEP_COLON) {
                    value = token.getValue();
                    jsonObject.put(key, value);
                    expectToken = SEP_COMMA_TOKEN | END_OBJECT_TOKEN;
                } else {
                    key = token.getValue();
                    expectToken = SEP_COLON_TOKEN;
                }
                    break;
                case SEP_COLON:
                    checkExpectToken(tokenType, expectToken);
                    expectToken = NULL_TOKEN | NUMBER_TOKEN | BOOLEAN_TOKEN | STRING_TOKEN | BEGIN_OBJECT_TOKEN | BEGIN_ARRAY_TOKEN;
                    break;
                case SEP_COMMA:
                    checkExpectToken(tokenType, expectToken);
                    expectToken = STRING_TOKEN;
                    break;
                case END_DOCUMENT:
                    checkExpectToken(tokenType, expectToken);
                    return jsonObject;
                default:
                    throw new JsonParseException("Unexpected Token.");
            }
        } throw new JsonParseException("Parse error, invalid Token.");
    }
 3.Gson解析原理

Gson在初始化是定义了不同数据类型的TypeAdapter用来定义对不同数据类型读写方法,包含基本数据类型例如String,Int,Float,Double,Date,Uri以及java对象,对象这些Adapter使用list集合保存起来,gson在对json串进行读取后,根据得到的不同的json数据类型,便会去找对应类型的Adapter对该类型进行读写,当读取到的是一个 { 时,便会使用 ReflectiveTypeAdapterFactory 通过反射创建相应的java对象, 使用相对应的TypeAdapter, 将读取到的key/value赋值给java对象的字段,不断的往后读取完成对象的属性的赋值,最终输出java对象

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/919298.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号