APIJSON(九:AbstractObjectParser源码阅读(6))
2021SC@SDUSC
onTableArrayParse
这个函数主要是用于实现批量新增或修改。
public void onTableArrayParse(String key, JSONArray value) throws Exception
然后生成childKey,其主要是key减去JSONRequest.KEY_ARRAY
String childKey = key.substring(0, key.length() - JSONRequest.KEY_ARRAY.length());
之后就是对一些变量的赋值了
JSONArray valueArray = (JSONArray) value;
int allCount = 0;
JSONArray ids = new JSONArray();
int version = parser.getVersion();
int maxUpdateCount = parser.getMaxUpdateCount();
String idKey = parser.createSQLConfig().getIdKey(); //Table[]: [{}] arrayConfig 为 null
boolean isNeedVerifyContent = parser.isNeedVerifyContent();
for循环
接下来是一个for循环
for (int i = 0; i < valueArray.size(); i++)
在循环中,会首先对valueArray对应的值进行判断,
JSONObject item;
try {
item = valueArray.getJSONObject(i);
}
catch (Exception e) {
throw new UnsupportedDataTypeException("批量新增/修改失败!" + key + "/" + i + ":value 中value不合法!类型必须是 OBJECT ,结构为 {} !");
}
具体使用了JSONArray中的getJSONObject方法。
其主要效果就是根据传入的index值判断对应的value值是否为JSONObject。如果是,就返回其value;如果不是,就判断是否为Map类型,返回map的value,或强制转换为JSONObject。
具体代码如下
public JSONObject getJSONObject(int index) {
Object value = this.list.get(index);
if (value instanceof JSONObject) {
return (JSONObject)value;
} else {
return value instanceof Map ? new JSONObject((Map)value) : (JSONObject)toJSON(value);
}
}
JSONObject.toJSON(object) 来处理Javabean的,这样处理简单的对象是没有问题的,但是对象如果复杂的话就会发生一些问题。
object对象过于复杂和大量时,用toJSOn解析就会出现CPU、内存一直飙升,JVM一直执行GC操作,但是无法回收内存,最后会报java.lang.OutOfMemoryError: GC overhead limit exceeded 错误。
如果出现错误的话,就会抛出value类型不合法的错误
接下来是继续设置初始值,并使用了之前分析过的onChildParse函数来解析子对象。
注意这里success的值为JSONResponse中的isSuccess的值,而count的值由result决定。
JSONRequest req = new JSONRequest(childKey, item);
JSONObject result = (JSONObject) onChildParse(0, "" + i, isNeedVerifyContent == false ? req : parser.parseCorrectRequest(method, childKey, version, "", req, maxUpdateCount, parser));
result = result.getJSONObject(childKey);
boolean success = JSONResponse.isSuccess(result);
int count = result == null ? null : result.getIntValue(JSONResponse.KEY_COUNT);
如果success为false或count不等于1,就会报错。
if (success == false || count != 1) { //如果 code = 200 但 count != 1,不能算成功,掩盖了错误不好排查问题
throw new ServerException("批量新增/修改失败!" + key + "/" + i + ":" + (success ? "成功但 count != 1 !" : (result == null ? "null" : result.getString(JSONResponse.KEY_MSG))));
}
最后加上count值且在ids中加入result中的idkey
allCount += count;
ids.add(result.get(idKey));
for循环外
之后获取获取请求成功的状态内容,并在allResult中插入之前循环中的allCount和ids
JSONObject allResult = AbstractParser.newSuccessResult();
allResult.put(JSONResponse.KEY_COUNT, allCount);
allResult.put(idKey + "[]", ids);
response.put(childKey, allResult); //不按原样返回,避免数据量过大
最后在response中插入childKey和allResult。
至此AbstractObjectParser类中关键方法函数都已分析完毕。
回顾总结
AbstractObjectParser类主要是实现了ObjectParser接口。
其主要作用是用来解析传入的Object类。其主体方法是——
parse方法是用来解析成员的主要方法,其中根据不同情况,还包含了以下对应的方法
解析普通成员的onParse方法
解析子对象的onChildParse方法
解析赋值引用的onReferenceParse方法
修改数组 PUT key:[]的onPUTArrayParse方法
批量新增或修改的onTableArrayParse方法
AbstractObjectParser类中还有一些其他的方法如调用 parser 的 sqlExecutor 来解析结果的parseResponse方法以及配置SQL的setSQLConfig,执行 SQL的executeSQL等,在此就不多说了。
以下贴出与其相关的代码——
@Override
public JSONObject parseResponse(RequestMethod method, String table, String alias, JSONObject request, List<Join> joinList, boolean isProcedure) throws Exception {
SQLConfig config = newSQLConfig(method, table, alias, request, joinList, isProcedure);
return parseResponse(config, isProcedure);
}
@Override
public JSONObject parseResponse(SQLConfig config, boolean isProcedure) throws Exception {
if (parser.getSQLExecutor() == null) {
parser.createSQLExecutor();
}
return parser.getSQLExecutor().execute(config, isProcedure);
}
@Override
public SQLConfig newSQLConfig(boolean isProcedure) throws Exception {
return newSQLConfig(method, table, alias, sqlRequest, joinList, isProcedure);
}
/**SQL 配置,for single object
* @return {@link #setSQLConfig(int, int, int)}
* @throws Exception
*/
@Override
public AbstractObjectParser setSQLConfig() throws Exception {
return setSQLConfig(RequestMethod.isQueryMethod(method) ? 1 : 0, 0, 0);
}
@Override
public AbstractObjectParser setSQLConfig(int count, int page, int position) throws Exception {
if (isTable == false || isReuse) {
return setPosition(position);
}
if (sqlConfig == null) {
try {
sqlConfig = newSQLConfig(false);
}
catch (NotExistException e) {
e.printStackTrace();
return this;
}
}
sqlConfig.setCount(sqlConfig.getCount() <= 0 ? count : sqlConfig.getCount()).setPage(page).setPosition(position);
parser.onVerifyRole(sqlConfig);
return this;
}
public AbstractObjectParser executeSQL() throws Exception {
//执行SQL操作数据库
if (isTable == false) {//提高性能
sqlReponse = new JSONObject(sqlRequest);
}
else {
try {
sqlReponse = onSQLExecute();
}
catch (NotExistException e) {
sqlReponse = null;//内部吃掉异常,put到最外层
}
}
if (drop) {//丢弃Table,只为了向下提供条件
sqlReponse = null;
}
return this;
}
/**
* @return response
* @throws Exception
*/
@Override
public JSONObject response() throws Exception {
if (sqlReponse == null || sqlReponse.isEmpty()) {
if (isTable) {//Table自身都获取不到值,则里面的Child都无意义,不需要再解析
return null; // response;
}
} else {
response.putAll(sqlReponse);
}
//把isTable时取出去的custom重新添加回来
if (customMap != null) {
response.putAll(customMap);
}
onFunctionResponse("0");
onChildResponse();
onFunctionResponse("+");
onComplete();
return response;
}
}
//把isTable时取出去的custom重新添加回来
if (customMap != null) {
response.putAll(customMap);
}
onFunctionResponse("0");
onChildResponse();
onFunctionResponse("+");
onComplete();
return response;
}