APIJSON(九:AbstractObjectParser源码阅读(6))

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;
}

猜你喜欢

转载自blog.csdn.net/qq_50861917/article/details/121580226