|
47 | 47 | */ |
48 | 48 | public abstract class AbstractParser<T extends Object> implements Parser<T>, ParserCreator<T>, VerifierCreator<T>, SQLCreator { |
49 | 49 | protected static final String TAG = "AbstractParser"; |
50 | | - |
| 50 | + protected Map<Object, RequestMethod> key_method_Map = new HashMap<>(); |
51 | 51 | /** |
52 | 52 | * 可以通过切换该变量来控制是否打印关键的接口请求内容。保守起见,该值默认为false。 |
53 | 53 | * 与 {@link Log#DEBUG} 任何一个为 true 都会打印关键的接口请求内容。 |
@@ -572,28 +572,11 @@ public JSONObject parseCorrectRequest(RequestMethod method, String tag, int vers |
572 | 572 | return request;//需要指定JSON结构的get请求可以改为post请求。一般只有对安全性要求高的才会指定,而这种情况用明文的GET方式几乎肯定不安全 |
573 | 573 | } |
574 | 574 |
|
575 | | - if (StringUtil.isEmpty(tag, true)) { |
576 | | - throw new IllegalArgumentException("请在最外层传 tag !一般是 Table 名,例如 \"tag\": \"User\" "); |
577 | | - } |
578 | | - |
579 | | - //获取指定的JSON结构 <<<<<<<<<<<< |
580 | | - JSONObject object = null; |
581 | | - String error = ""; |
582 | | - try { |
583 | | - object = getStructure("Request", method.name(), tag, version); |
584 | | - } catch (Exception e) { |
585 | | - error = e.getMessage(); |
586 | | - } |
587 | | - if (object == null) { //empty表示随意操作 || object.isEmpty()) { |
588 | | - throw new UnsupportedOperationException("找不到 version: " + version + ", method: " + method.name() + ", tag: " + tag + " 对应的 structure !" |
589 | | - + "非开放请求必须是后端 Request 表中校验规则允许的操作!\n " + error + "\n如果需要则在 Request 表中新增配置!"); |
590 | | - } |
591 | | - |
592 | | - //获取指定的JSON结构 >>>>>>>>>>>>>> |
593 | | - JSONObject target = wrapRequest(method, tag, object, true); |
| 575 | +// if (StringUtil.isEmpty(tag, true)) { |
| 576 | +// throw new IllegalArgumentException("请在最外层传 tag !一般是 Table 名,例如 \"tag\": \"User\" "); |
| 577 | +// } |
594 | 578 |
|
595 | | - //JSONObject clone 浅拷贝没用,Structure.parse 会导致 structure 里面被清空,第二次从缓存里取到的就是 {} |
596 | | - return getVerifier().verifyRequest(method, name, target, request, maxUpdateCount, getGlobalDatabase(), getGlobalSchema(), creator); |
| 579 | + return batchVerify(method, tag, version, name, request, maxUpdateCount, creator); |
597 | 580 | } |
598 | 581 |
|
599 | 582 |
|
@@ -1047,6 +1030,8 @@ public JSONObject onObjectParse(final JSONObject request |
1047 | 1030 | if (op == null) { |
1048 | 1031 | op = createObjectParser(request, parentPath, arrayConfig, isSubquery, isTable, isArrayMainTable); |
1049 | 1032 | } |
| 1033 | + // 对象 - 设置 method |
| 1034 | + setOpMethod(request, op, name); |
1050 | 1035 | op = op.parse(name, isReuse); |
1051 | 1036 |
|
1052 | 1037 | JSONObject response = null; |
@@ -2022,7 +2007,8 @@ protected void onBegin() { |
2022 | 2007 | */ |
2023 | 2008 | protected void onCommit() { |
2024 | 2009 | // Log.d(TAG, "onCommit >>"); |
2025 | | - if (RequestMethod.isQueryMethod(requestMethod)) { |
| 2010 | + // this.sqlExecutor.getTransactionIsolation() 只有json第一次执行才会设置, get请求=0 |
| 2011 | + if (RequestMethod.isQueryMethod(requestMethod) && this.sqlExecutor.getTransactionIsolation() == Connection.TRANSACTION_NONE ) { |
2026 | 2012 | return; |
2027 | 2013 | } |
2028 | 2014 |
|
@@ -2068,4 +2054,163 @@ protected void onClose() { |
2068 | 2054 | queryResultMap = null; |
2069 | 2055 | } |
2070 | 2056 |
|
| 2057 | + private void setOpMethod(JSONObject request,ObjectParser op, String key) { |
| 2058 | + if(key != null && request.getString(apijson.JSONObject.KEY_METHOD) != null) { |
| 2059 | + String _method = request.getString(apijson.JSONObject.KEY_METHOD); |
| 2060 | + if( _method != null) { |
| 2061 | + RequestMethod method = RequestMethod.valueOf(_method.toUpperCase()); |
| 2062 | + this.setMethod(method); |
| 2063 | + op.setMethod(method); |
| 2064 | + } |
| 2065 | + } |
| 2066 | + } |
| 2067 | + |
| 2068 | + protected JSONObject getRequestStructure(RequestMethod method, String tag, int version) throws Exception { |
| 2069 | + // 获取指定的JSON结构 <<<<<<<<<<<< |
| 2070 | + JSONObject object = null; |
| 2071 | + String error = ""; |
| 2072 | + try { |
| 2073 | + object = getStructure("Request", method.name(), tag, version); |
| 2074 | + } catch (Exception e) { |
| 2075 | + error = e.getMessage(); |
| 2076 | + } |
| 2077 | + if (object == null) { // empty表示随意操作 || object.isEmpty()) { |
| 2078 | + throw new UnsupportedOperationException("找不到 version: " + version + ", method: " + method.name() + ", tag: " + tag + " 对应的 structure !" + "非开放请求必须是后端 Request 表中校验规则允许的操作!\n " + error + "\n如果需要则在 Request 表中新增配置!"); |
| 2079 | + } |
| 2080 | + return object; |
| 2081 | + } |
| 2082 | + |
| 2083 | + private JSONObject batchVerify(RequestMethod method, String tag, int version, String name, @NotNull JSONObject request, int maxUpdateCount, SQLCreator creator) throws Exception { |
| 2084 | + JSONObject jsonObject = new JSONObject(true); |
| 2085 | + if (request.keySet() == null || request.keySet().size() == 0) { |
| 2086 | + throw new IllegalArgumentException("json对象格式不正确 !,例如 \"User\": {}"); |
| 2087 | + } |
| 2088 | + |
| 2089 | + for (String key : request.keySet()) { |
| 2090 | + // key重复直接抛错(xxx:alias, xxx:alias[]) |
| 2091 | + if (jsonObject.containsKey(key) || jsonObject.containsKey(key + apijson.JSONObject.KEY_ARRAY)) { |
| 2092 | + throw new IllegalArgumentException("对象名重复,请添加别名区分 ! ,重复对象名为: " + key); |
| 2093 | + } |
| 2094 | + |
| 2095 | + // @post、@get等RequestMethod |
| 2096 | + try { |
| 2097 | + if (key.startsWith("@")) { |
| 2098 | + try { |
| 2099 | + // 如果不匹配,不处理即可 |
| 2100 | + RequestMethod l_method = RequestMethod.valueOf(key.substring(1).toUpperCase()); |
| 2101 | + if (l_method != null) { |
| 2102 | + if (request.get(key) instanceof JSONArray) { |
| 2103 | + for (Object objKey : request.getJSONArray(key)) { |
| 2104 | + key_method_Map.put(objKey, l_method); |
| 2105 | + } |
| 2106 | + continue; |
| 2107 | + } else { |
| 2108 | + throw new IllegalArgumentException("参数 " + key + " 必须是数组格式 ! ,例如: [\"Moment\", \"Comment[]\"]"); |
| 2109 | + } |
| 2110 | + } |
| 2111 | + } catch (Exception e) { |
| 2112 | + } |
| 2113 | + } |
| 2114 | + |
| 2115 | + // 如果对象设置了@method, 优先使用 对象内部的@method |
| 2116 | + // 对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法 |
| 2117 | + // 将method 设置到每个object, op执行会解析 |
| 2118 | + if (request.get(key) instanceof JSONObject) { |
| 2119 | + if(request.getJSONObject(key).getString(apijson.JSONObject.KEY_METHOD) == null) { |
| 2120 | + if (key_method_Map.get(key) == null) { |
| 2121 | + // 数组会解析为对象进行校验,做一下兼容 |
| 2122 | + if(key_method_Map.get(key + apijson.JSONObject.KEY_ARRAY) == null) { |
| 2123 | + request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, method); |
| 2124 | + }else { |
| 2125 | + request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, key_method_Map.get(key + apijson.JSONObject.KEY_ARRAY)); |
| 2126 | + } |
| 2127 | + } else { |
| 2128 | + request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, key_method_Map.get(key)); |
| 2129 | + } |
| 2130 | + } |
| 2131 | + |
| 2132 | + // get请求不校验 |
| 2133 | + RequestMethod _method = RequestMethod.valueOf(request.getJSONObject(key).getString(apijson.JSONObject.KEY_METHOD).toUpperCase()); |
| 2134 | + if (RequestMethod.isPublicMethod(_method)) { |
| 2135 | + jsonObject.put(key, request.getJSONObject(key)); |
| 2136 | + continue; |
| 2137 | + } |
| 2138 | + } |
| 2139 | + |
| 2140 | + if (key.startsWith("@") || key.endsWith("@")) { |
| 2141 | + jsonObject.put(key, request.get(key)); |
| 2142 | + continue; |
| 2143 | + } |
| 2144 | + |
| 2145 | + |
| 2146 | + if (request.get(key) instanceof JSONObject || request.get(key) instanceof JSONArray) { |
| 2147 | + RequestMethod _method = null; |
| 2148 | + if (request.get(key) instanceof JSONObject) { |
| 2149 | + _method = RequestMethod.valueOf(request.getJSONObject(key).getString(apijson.JSONObject.KEY_METHOD).toUpperCase()); |
| 2150 | + } else { |
| 2151 | + if (key_method_Map.get(key) == null) { |
| 2152 | + _method = method; |
| 2153 | + } else { |
| 2154 | + _method = key_method_Map.get(key); |
| 2155 | + } |
| 2156 | + } |
| 2157 | + |
| 2158 | + String _tag = buildTag(request, key); |
| 2159 | + JSONObject requestItem = new JSONObject(); |
| 2160 | + requestItem.put(_tag, request.get(key)); |
| 2161 | + JSONObject object = getRequestStructure(_method, _tag, version); |
| 2162 | + JSONObject ret = objectVerify(_method, _tag, version, name, requestItem, maxUpdateCount, creator, object); |
| 2163 | + jsonObject.put(key, ret.get(_tag)); |
| 2164 | + } else { |
| 2165 | + jsonObject.put(key, request.get(key)); |
| 2166 | + } |
| 2167 | + } catch (Exception e) { |
| 2168 | + e.printStackTrace(); |
| 2169 | + throw new Exception(e); |
| 2170 | + } |
| 2171 | + } |
| 2172 | + |
| 2173 | + return jsonObject; |
| 2174 | + } |
| 2175 | + |
| 2176 | + /** |
| 2177 | + * { "xxx:aa":{ "@tag": "" }, "tag": "User" } |
| 2178 | + * 1、@tag存在,tag=@tag |
| 2179 | + * 2、@tag不存在 |
| 2180 | + * 生成规则: |
| 2181 | + * 1、存在别名 |
| 2182 | + * key=对象: tag=key去除别名 |
| 2183 | + * key=数组: tag=key去除别名 + [] |
| 2184 | + * 2、不存在别名 |
| 2185 | + * tag=key |
| 2186 | + * tag=key + [] |
| 2187 | + * @param request |
| 2188 | + * @param key |
| 2189 | + * @return |
| 2190 | + */ |
| 2191 | + private String buildTag(JSONObject request, String key) { |
| 2192 | + String _tag = null; |
| 2193 | + if (request.get(key) instanceof JSONObject && request.getJSONObject(key).getString("@tag") != null) { |
| 2194 | + _tag = request.getJSONObject(key).getString("@tag"); |
| 2195 | + } else { |
| 2196 | + int keyIndex = key.indexOf(":"); |
| 2197 | + if (keyIndex != -1) { |
| 2198 | + _tag = key.substring(0, keyIndex); |
| 2199 | + if (apijson.JSONObject.isTableArray(key)) { |
| 2200 | + _tag += apijson.JSONObject.KEY_ARRAY; |
| 2201 | + } |
| 2202 | + } else { |
| 2203 | + // 不存在别名 |
| 2204 | + _tag = key; |
| 2205 | + } |
| 2206 | + } |
| 2207 | + return _tag; |
| 2208 | + } |
| 2209 | + |
| 2210 | + protected JSONObject objectVerify(RequestMethod method, String tag, int version, String name, @NotNull JSONObject request, int maxUpdateCount, SQLCreator creator, JSONObject object) throws Exception { |
| 2211 | + // 获取指定的JSON结构 >>>>>>>>>>>>>> |
| 2212 | + JSONObject target = wrapRequest(method, tag, object, true); |
| 2213 | + // JSONObject clone 浅拷贝没用,Structure.parse 会导致 structure 里面被清空,第二次从缓存里取到的就是 {} |
| 2214 | + return getVerifier().verifyRequest(method, name, target, request, maxUpdateCount, getGlobalDatabase(), getGlobalSchema(), creator); |
| 2215 | + } |
2071 | 2216 | } |
0 commit comments