2021SC@SDUSC
APIJSON代码分析—JSONRequest类
我们在前面基本每一次的分析中都会看到有这个JSONObiect对象,其实这就是我们在前端请求数据时需要发送或者传输的数据格式。
JSONRequest是一个继承于JSONObject类的类,而这个JSONObject类让我们来看一下:
class JSONObject extends com.alibaba.fastjson.JSONObject
它其实是继承fastjson的JSONObject类,
这个类的作用有比如存放关键字:
public static final String KEY_TRY = "@try"; //尝试,忽略异常
public static final String KEY_CATCH = "@catch"; //TODO 捕捉到异常后,处理方式 null-不处理;DEFAULT-返回默认值;ORIGIN-返回请求里的原始值
public static final String KEY_DROP = "@drop"; //丢弃,不返回,TODO 应该通过 fastjson 的 ignore 之类的机制来处理,避免导致下面的对象也不返回
// public static final String KEY_KEEP = "@keep"; //一定会返回,为 null 或 空对象时,会使用默认值(非空),解决其它对象因为不关联的第一个对为空导致也不返回
public static final String KEY_DEFULT = "@default"; //TODO 自定义默认值 { "@default":true },@default 可完全替代 @keep
public static final String KEY_NULL = "@null"; //TODO 值为 null 的键值对 "@null":"tag,pictureList",允许 is NULL 条件判断, SET tag = NULL 修改值为 NULL 等
public static final String KEY_ROLE = "@role"; //角色,拥有对某些数据的某些操作的权限
public static final String KEY_DATABASE = "@database"; //数据库类型,默认为MySQL
public static final String KEY_SCHEMA = "@schema"; //数据库,Table在非默认schema内时需要声明
public static final String KEY_DATASOURCE = "@datasource"; //数据源
public static final String KEY_EXPLAIN = "@explain"; //分析 true/false
public static final String KEY_CACHE = "@cache"; //缓存 RAM/ROM/ALL
public static final String KEY_COLUMN = "@column"; //查询的Table字段或SQL函数
public static final List<String> TABLE_KEY_LIST;
static {
TABLE_KEY_LIST = new ArrayList<String>();
TABLE_KEY_LIST.add(KEY_ROLE);
TABLE_KEY_LIST.add(KEY_DATABASE);
TABLE_KEY_LIST.add(KEY_SCHEMA);
TABLE_KEY_LIST.add(KEY_DATASOURCE);
TABLE_KEY_LIST.add(KEY_EXPLAIN);
TABLE_KEY_LIST.add(KEY_CACHE);
TABLE_KEY_LIST.add(KEY_COLUMN);
}
然后就是getter,setter的方法,还有一个比较重要的方法,(也就是put方法),这个方法是重写了fastjson的put方法,但其实在其中就是调用了其父类的put方法也就是super,put(key,value):
@Override
public Object put(String key, Object value) {
if (value == null) {
Log.e(TAG, "put value == null >> return null;");
return null;
}
if (StringUtil.isEmpty(key, true)) {
Class<?> clazz = value.getClass(); //should not return null
if (clazz.getAnnotation(MethodAccess.class) == null) {
throw new IllegalArgumentException("puts StringUtil.isEmpty(key, true)" +
" clazz.getAnnotation(MethodAccess.class) == null" +
" \n key为空时仅支持 类型被@MethodAccess注解 的value !!!" +
" \n 如果一定要这么用,请对 " + clazz.getName() + " 注解!" +
" \n 如果是类似 key[]:{} 结构的请求,建议用 putsAll(...) !");
}
key = value.getClass().getSimpleName();
}
return super.put(key, value);
}
这个方法其实就是先对要放入的key和value进行一个判断,如果传入的value为null的话,那么则直接返回null,如果value值存在,那么就对key进行判断,判断的时候要用StringUtil类的isEmpty方法,而不是我们所说的判断空字符。
这其实是由一定的解释的,经常编程或者有成熟的软件工程经验的工程师都知道,由于有时候我们的string可能为null,也有可能是空字符等情况,所以我们对string类型进行判断的时候,一般都要自己写一个工具类去判断,而在,作者就是增加了对null的一个判断,然后调用了系统的isEmpty,系统的方法作用是根据一个Byte的值的长度,也就是字节的长度来判断空。
这里这里面还有一个trim参数,trim是一个布尔变量,在其父类里面可以看到,在里面是继续调用了trim()方法,作用就是将字符的头尾空格去除,然后就是在key为空的时候去获取到这个方法所在类的className,让这个className作为我们的key值。
然后我们回到当前类:
public static final String KEY_TAG = "tag";
public static final String KEY_VERSION = "version";
public static final String KEY_FORMAT = "format";
这里要注意这些标签只在最外层,且最外层用JSONRequest
,然后就是同样于其父类:
public static final int QUERY_TABLE = 0;
public static final int QUERY_TOTAL = 1;
public static final int QUERY_ALL = 2;
public static final String QUERY_TABLE_STRING = "TABLE";
public static final String QUERY_TOTAL_STRING = "TOTAL";
public static final String QUERY_ALL_STRING = "ALL";
public static final String SUBQUERY_RANGE_ALL = "ALL";
public static final String SUBQUERY_RANGE_ANY = "ANY";
public static final String KEY_QUERY = "query";
public static final String KEY_COUNT = "count";
public static final String KEY_PAGE = "page";
public static final String KEY_JOIN = "join";
public static final String KEY_SUBQUERY_RANGE = "range";
public static final String KEY_SUBQUERY_FROM = "from";
public static final List<String> ARRAY_KEY_LIST;
static {
ARRAY_KEY_LIST = new ArrayList<String>();
ARRAY_KEY_LIST.add(KEY_QUERY);
ARRAY_KEY_LIST.add(KEY_COUNT);
ARRAY_KEY_LIST.add(KEY_PAGE);
ARRAY_KEY_LIST.add(KEY_JOIN);
ARRAY_KEY_LIST.add(KEY_SUBQUERY_RANGE);
ARRAY_KEY_LIST.add(KEY_SUBQUERY_FROM);
}
就是去定义一些关键字,这写的作用呢在前面分析AbstractObjectParser类的时候已经大致讲过一些,就是用来保存JSONRequest的各种状态,以便于回来解析的时候更加便捷的进行操作,其实在调用所需要的fastjson里面的JSONObject里面就是编码了那些,write和read,也就是解析与发送,我们的序列化与反序列话也同样是在这里面完成的,因为我们前后端合并,但还是急需要进行数据的传输,我们就对其Request和Response进行序列化和反序列化,这样也就是我们的request和response的职责与功能所在。