Skip to content

Commit 2ea3700

Browse files
authored
fix: make mixed CRUD method directives order-independent, thx to 014-code #867
#867
2 parents d86a640 + c01a4e5 commit 2ea3700

4 files changed

Lines changed: 323 additions & 90 deletions

File tree

APIJSONORM/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
</properties>
2222

2323
<dependencies>
24+
<dependency>
25+
<groupId>junit</groupId>
26+
<artifactId>junit</artifactId>
27+
<version>4.13.2</version>
28+
<scope>test</scope>
29+
</dependency>
2430
</dependencies>
2531

2632
<build>

APIJSONORM/src/main/java/apijson/orm/AbstractParser.java

Lines changed: 101 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,6 +2303,86 @@ protected M getRequestStructure(RequestMethod method, String tag, int version) t
23032303
KEY_METHOD_ENUM_MAP.put(KEY_DELETE, RequestMethod.DELETE);
23042304
}
23052305

2306+
private void parseMethodDirective(String key, RequestMethod keyMethod, @NotNull M request) throws Exception {
2307+
boolean isPost = KEY_POST.equals(key);
2308+
Object val = request.get(key);
2309+
Map<String, Object> obj = val instanceof Map<?, ?> ? JSON.get(request, key) : null;
2310+
if (obj == null) {
2311+
if (val instanceof String) {
2312+
String[] tbls = StringUtil.split((String) val);
2313+
if (tbls != null && tbls.length > 0) {
2314+
obj = new LinkedHashMap<String, Object>();
2315+
for (String tbl : tbls) {
2316+
if (obj.containsKey(tbl)) {
2317+
throw new ConflictException(key + ": value 中 " + tbl + " 已经存在,不能重复!");
2318+
}
2319+
2320+
obj.put(tbl, isPost && isTableArray(tbl)
2321+
? tbl.substring(0, tbl.length() - 2) + ":[]" : "");
2322+
}
2323+
}
2324+
}
2325+
else {
2326+
throw new IllegalArgumentException(key + ": value 中 value 类型错误,只能是 String 或 Map<String, Object> {} !");
2327+
}
2328+
}
2329+
2330+
Set<Entry<String, Object>> set = obj == null ? new HashSet<>() : obj.entrySet();
2331+
for (Entry<String, Object> objEntry : set) {
2332+
String objKey = objEntry == null ? null : objEntry.getKey();
2333+
if (objKey == null) {
2334+
continue;
2335+
}
2336+
2337+
Map<String, Object> objAttrMap = new HashMap<>();
2338+
objAttrMap.put(KEY_METHOD, keyMethod);
2339+
keyObjectAttributesMap.put(objKey, objAttrMap);
2340+
2341+
Object objVal = objEntry.getValue();
2342+
Map<String, Object> objAttrJson = objVal instanceof Map<?, ?> ? JSON.getMap(obj, objKey) : null;
2343+
if (objAttrJson == null) {
2344+
if (objVal instanceof String) {
2345+
objAttrMap.put(KEY_TAG, "".equals(objVal) ? objKey : objVal);
2346+
}
2347+
else {
2348+
throw new IllegalArgumentException(key + ": { " + objKey + ": value 中 value 类型错误,只能是 String 或 Map<String, Object> {} !");
2349+
}
2350+
}
2351+
else {
2352+
boolean hasTag = false;
2353+
for (Entry<String, Object> entry : objAttrJson.entrySet()) {
2354+
String objAttrKey = entry == null ? null : entry.getKey();
2355+
if (objAttrKey == null) {
2356+
continue;
2357+
}
2358+
2359+
switch (objAttrKey) {
2360+
case KEY_DATABASE:
2361+
case KEY_DATASOURCE:
2362+
case KEY_NAMESPACE:
2363+
case KEY_CATALOG:
2364+
case KEY_SCHEMA:
2365+
case KEY_VERSION:
2366+
case KEY_ROLE:
2367+
objAttrMap.put(objAttrKey, entry.getValue());
2368+
break;
2369+
case KEY_TAG:
2370+
hasTag = true;
2371+
objAttrMap.put(objAttrKey, entry.getValue());
2372+
break;
2373+
default:
2374+
break;
2375+
}
2376+
}
2377+
2378+
if (hasTag == false) {
2379+
objAttrMap.put(KEY_TAG, isPost && isTableArray(objKey)
2380+
? objKey.substring(0, objKey.length() - 2) + ":[]" : objKey);
2381+
}
2382+
}
2383+
}
2384+
}
2385+
23062386
protected M batchVerify(RequestMethod method, String tag, int version, String name, @NotNull M request, int maxUpdateCount, SQLCreator<T, M, L> creator) throws Exception {
23072387
M correctRequest = JSON.createJSONObject();
23082388
List<String> removeTmpKeys = new ArrayList<>(); // 请求json里面的临时变量,不需要带入后面的业务中,比如 @post、@get等
@@ -2312,103 +2392,34 @@ protected M batchVerify(RequestMethod method, String tag, int version, String na
23122392
throw new IllegalArgumentException("JSON 对象格式不正确 !正确示例例如 \"User\": {}");
23132393
}
23142394

2395+
// 先收集所有显式方法,避免同一请求中方法指令的字段顺序影响对象解析结果。
23152396
for (String key : reqSet) {
2316-
// key 重复直接抛错(xxx:alias, xxx:alias[])
2317-
if (correctRequest.containsKey(key) || correctRequest.containsKey(key + KEY_ARRAY)) {
2318-
throw new IllegalArgumentException("对象名重复,请添加别名区分 ! 重复对象名为: " + key);
2397+
RequestMethod keyMethod = KEY_POST.equals(key) ? RequestMethod.POST : KEY_METHOD_ENUM_MAP.get(key);
2398+
if (keyMethod == null) {
2399+
continue;
23192400
}
23202401

2321-
boolean isPost = KEY_POST.equals(key);
2322-
// @post、@get 等 RequestMethod
2402+
removeTmpKeys.add(key);
23232403
try {
2324-
RequestMethod keyMethod = isPost ? RequestMethod.POST : KEY_METHOD_ENUM_MAP.get(key);
2325-
if (keyMethod != null) {
2326-
// 如果不匹配,异常不处理即可
2327-
removeTmpKeys.add(key);
2328-
2329-
Object val = request.get(key);
2330-
Map<String, Object> obj = val instanceof Map<?, ?> ? JSON.get(request, key) : null;
2331-
if (obj == null) {
2332-
if (val instanceof String) {
2333-
String[] tbls = StringUtil.split((String) val);
2334-
if (tbls != null && tbls.length > 0) {
2335-
obj = new LinkedHashMap<String, Object>();
2336-
for (int i = 0; i < tbls.length; i++) {
2337-
String tbl = tbls[i];
2338-
if (obj.containsKey(tbl)) {
2339-
throw new ConflictException(key + ": value 中 " + tbl + " 已经存在,不能重复!");
2340-
}
2341-
2342-
obj.put(tbl, isPost && isTableArray(tbl)
2343-
? tbl.substring(0, tbl.length() - 2) + ":[]" : "");
2344-
}
2345-
}
2346-
}
2347-
else {
2348-
throw new IllegalArgumentException(key + ": value 中 value 类型错误,只能是 String 或 Map<String, Object> {} !");
2349-
}
2350-
}
2351-
2352-
Set<Entry<String, Object>> set = obj == null ? new HashSet<>() : obj.entrySet();
2353-
2354-
for (Entry<String, Object> objEntry : set) {
2355-
String objKey = objEntry == null ? null : objEntry.getKey();
2356-
if (objKey == null) {
2357-
continue;
2358-
}
2359-
2360-
Map<String, Object> objAttrMap = new HashMap<>();
2361-
objAttrMap.put(KEY_METHOD, keyMethod);
2362-
keyObjectAttributesMap.put(objKey, objAttrMap);
2363-
2364-
Object objVal = objEntry.getValue();
2365-
Map<String, Object> objAttrJson = objVal instanceof Map<?, ?> ? JSON.getMap(obj, objKey) : null;
2366-
if (objAttrJson == null) {
2367-
if (objVal instanceof String) {
2368-
objAttrMap.put(KEY_TAG, "".equals(objVal) ? objKey : objVal);
2369-
}
2370-
else {
2371-
throw new IllegalArgumentException(key + ": { " + objKey + ": value 中 value 类型错误,只能是 String 或 Map<String, Object> {} !");
2372-
}
2373-
}
2374-
else {
2375-
Set<Entry<String, Object>> objSet = objAttrJson.entrySet();
2376-
2377-
boolean hasTag = false;
2378-
for (Entry<String, Object> entry : objSet) {
2379-
String objAttrKey = entry == null ? null : entry.getKey();
2380-
if (objAttrKey == null) {
2381-
continue;
2382-
}
2404+
parseMethodDirective(key, keyMethod, request);
2405+
}
2406+
catch (Exception e) {
2407+
Log.e(TAG, "parse method directive failed", e);
2408+
throw e;
2409+
}
2410+
}
23832411

2384-
switch (objAttrKey) {
2385-
case KEY_DATABASE:
2386-
case KEY_DATASOURCE:
2387-
case KEY_NAMESPACE:
2388-
case KEY_CATALOG:
2389-
case KEY_SCHEMA:
2390-
case KEY_VERSION:
2391-
case KEY_ROLE:
2392-
objAttrMap.put(objAttrKey, entry.getValue());
2393-
break;
2394-
case KEY_TAG:
2395-
hasTag = true;
2396-
objAttrMap.put(objAttrKey, entry.getValue());
2397-
break;
2398-
default:
2399-
break;
2400-
}
2401-
}
2412+
for (String key : reqSet) {
2413+
// key 重复直接抛错(xxx:alias, xxx:alias[])
2414+
if (correctRequest.containsKey(key) || correctRequest.containsKey(key + KEY_ARRAY)) {
2415+
throw new IllegalArgumentException("对象名重复,请添加别名区分 ! 重复对象名为: " + key);
2416+
}
24022417

2403-
if (hasTag == false) {
2404-
objAttrMap.put(KEY_TAG, isPost && isTableArray(objKey)
2405-
? objKey.substring(0, objKey.length() - 2) + ":[]" : objKey);
2406-
}
2407-
}
2408-
}
2409-
continue;
2410-
}
2418+
if (KEY_POST.equals(key) || KEY_METHOD_ENUM_MAP.containsKey(key)) {
2419+
continue;
2420+
}
24112421

2422+
try {
24122423
// 1、非crud,对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法
24132424
// 2、crud, 没有声明就用 GET
24142425
// 3、兼容 sql@ Map<String, Object>,设置 GET方法

0 commit comments

Comments
 (0)