Skip to content

Commit 92ad9a1

Browse files
committed
Server:PUT 支持单独设置每项的批量修改,格式和 POST 批量新增相比多了 id;Structure 新增对 OBJECT[], ARRAY[] 的校验并优化代码;完善操作参数的 Operation 的注释;Operation,RequestRole 和正则匹配 COMPILE_MAP 中 key 强制名称大写
1 parent 0aad761 commit 92ad9a1

File tree

9 files changed

+240
-218
lines changed

9 files changed

+240
-218
lines changed

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoObjectParser.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535
public class DemoObjectParser extends AbstractObjectParser {
3636

3737
static {
38-
COMPILE_MAP.put("phone", StringUtil.PATTERN_PHONE);
39-
COMPILE_MAP.put("email", StringUtil.PATTERN_EMAIL);
40-
COMPILE_MAP.put("idCard", StringUtil.PATTERN_ID_CARD);
38+
COMPILE_MAP.put("PHONE", StringUtil.PATTERN_PHONE);
39+
COMPILE_MAP.put("EMAIL", StringUtil.PATTERN_EMAIL);
40+
COMPILE_MAP.put("ID_CARD", StringUtil.PATTERN_ID_CARD);
4141
}
4242

4343

APIJSON-Java-Server/APIJSONBoot/src/main/java/apijson/demo/server/DemoSQLConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ public String getUserIdKey(String database, String schema, String table) {
6767
return Controller.USER_.equals(table) || Controller.PRIVACY_.equals(table) ? KEY_ID : KEY_USER_ID; // id / userId
6868
}
6969

70-
//return null 则不生成 id,一般用于数据库自增 id
70+
//取消注释来实现数据库自增 id
7171
// @Override
7272
// public Object newId(RequestMethod method, String database, String schema, String table) {
73-
// return null;
73+
// return null; // return null 则不生成 id,一般用于数据库自增 id
7474
// }
7575
};
7676
}

APIJSON-Java-Server/APIJSONFinal/src/main/java/apijson/demo/server/DemoObjectParser.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535
public class DemoObjectParser extends AbstractObjectParser {
3636

3737
static {
38-
COMPILE_MAP.put("phone", StringUtil.PATTERN_PHONE);
39-
COMPILE_MAP.put("email", StringUtil.PATTERN_EMAIL);
40-
COMPILE_MAP.put("idCard", StringUtil.PATTERN_ID_CARD);
38+
COMPILE_MAP.put("PHONE", StringUtil.PATTERN_PHONE);
39+
COMPILE_MAP.put("EMAIL", StringUtil.PATTERN_EMAIL);
40+
COMPILE_MAP.put("ID_CARD", StringUtil.PATTERN_ID_CARD);
4141
}
4242

4343

APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/JSONObject.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.util.List;
1919
import java.util.Map;
2020

21+
import apijson.server.JSONRequest;
22+
2123
/**use this class instead of com.alibaba.fastjson.JSONObject
2224
* @author Lemon
2325
* @see #put
@@ -78,6 +80,13 @@ public static boolean isArrayKey(String key) {
7880
public static boolean isTableKey(String key) {
7981
return StringUtil.isBigName(key);
8082
}
83+
/**判断是否为对应Table数组的 key
84+
* @param key
85+
* @return
86+
*/
87+
public static boolean isTableArray(String key) {
88+
return isArrayKey(key) && isTableKey(key.substring(0, key.length() - KEY_ARRAY.length()));
89+
}
8190
//judge >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
8291

8392

APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/RequestRole.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static RequestRole get(String name) throws Exception {
6060
return null;
6161
}
6262
try { //Enum.valueOf只要找不到对应的值就会抛异常
63-
return RequestRole.valueOf(StringUtil.toUpperCase(name));
63+
return RequestRole.valueOf(name);
6464
} catch (Exception e) {
6565
throw new IllegalArgumentException("角色 " + name + " 不存在!只能是[" + StringUtil.getString(NAMES) + "]中的一种!", e);
6666
}

APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/AbstractObjectParser.java

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import java.util.Set;
3434
import java.util.regex.Pattern;
3535

36+
import javax.activation.UnsupportedDataTypeException;
37+
3638
import com.alibaba.fastjson.JSON;
3739
import com.alibaba.fastjson.JSONArray;
3840
import com.alibaba.fastjson.JSONObject;
@@ -244,45 +246,13 @@ public AbstractObjectParser parse() throws Exception {
244246
index ++;
245247
}
246248
}
249+
else if ((method == POST || method == PUT) && value instanceof JSONArray && JSONRequest.isTableArray(key)) { //JSONArray,批量新增或修改,往下一级提取
250+
onTableArrayParse(key, (JSONArray) value);
251+
}
247252
else if (method == PUT && value instanceof JSONArray
248253
&& (whereList == null || whereList.contains(key) == false)) { //PUT JSONArray
249254
onPUTArrayParse(key, (JSONArray) value);
250255
}
251-
else if (method == POST && value instanceof JSONArray && key.endsWith("[]") && JSONRequest.isTableKey(key.substring(0, key.length() - 2))) { //JSONArray,批量新增,往下一级提取
252-
String childKey = key.substring(0, key.length() - 2);
253-
JSONArray valueArray = (JSONArray) value;
254-
255-
int allCount = 0;
256-
JSONArray ids = new JSONArray();
257-
258-
int version = parser.getVersion();
259-
int maxUpdateCount = parser.getMaxUpdateCount();
260-
261-
for (int i = 0; i < valueArray.size(); i++) { //只要有一条失败,则抛出异常,全部失败
262-
//TODO 改成一条多 VALUES 的 SQL 性能更高,报错也更会更好处理,更人性化
263-
JSONRequest req = new JSONRequest(childKey, valueArray.getJSONObject(i));
264-
265-
//parser.getMaxSQLCount() ? 可能恶意调用接口,把数据库拖死
266-
JSONObject result = (JSONObject) onChildParse(0, "" + i, parser.parseCorrectRequest(method, childKey, version, "", req, maxUpdateCount, parser));
267-
result = result.getJSONObject(childKey);
268-
//
269-
boolean success = JSONResponse.isSuccess(result);
270-
int count = result == null ? null : result.getIntValue(JSONResponse.KEY_COUNT);
271-
272-
if (success == false || count != 1) { //如果 code = 200 但 count != 1,不能算成功,掩盖了错误为不好排查问题
273-
throw new ServerException("批量新增失败!" + key + "/" + i + ":" + (success ? "成功但 count != 1 !" : (result == null ? "null" : result.getString(JSONResponse.KEY_MSG))));
274-
}
275-
276-
allCount += count;
277-
ids.add(result.get(JSONResponse.KEY_ID));
278-
}
279-
280-
JSONObject allResult = AbstractParser.newSuccessResult();
281-
allResult.put(JSONResponse.KEY_ID_IN, ids);
282-
allResult.put(JSONResponse.KEY_COUNT, allCount);
283-
284-
response.put(key, allResult); //不按原样返回,避免数据量过大
285-
}
286256
else {//JSONArray或其它Object,直接填充
287257
if (onParse(key, value) == false) {
288258
invalidate();
@@ -597,6 +567,52 @@ public void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throw
597567

598568
}
599569

570+
571+
@Override
572+
public void onTableArrayParse(String key, JSONArray value) throws Exception {
573+
String childKey = key.substring(0, key.length() - JSONRequest.KEY_ARRAY.length());
574+
JSONArray valueArray = (JSONArray) value;
575+
576+
int allCount = 0;
577+
JSONArray ids = new JSONArray();
578+
579+
int version = parser.getVersion();
580+
int maxUpdateCount = parser.getMaxUpdateCount();
581+
582+
for (int i = 0; i < valueArray.size(); i++) { //只要有一条失败,则抛出异常,全部失败
583+
//TODO 改成一条多 VALUES 的 SQL 性能更高,报错也更会更好处理,更人性化
584+
JSONObject item;
585+
try {
586+
item = valueArray.getJSONObject(i);
587+
}
588+
catch (Exception e) {
589+
throw new UnsupportedDataTypeException("批量新增/修改失败!" + key + "/" + i + ":value 中value不合法!类型必须是 OBJECT ,结构为 {} !");
590+
}
591+
JSONRequest req = new JSONRequest(childKey, item);
592+
593+
//parser.getMaxSQLCount() ? 可能恶意调用接口,把数据库拖死
594+
JSONObject result = (JSONObject) onChildParse(0, "" + i, parser.parseCorrectRequest(method, childKey, version, "", req, maxUpdateCount, parser));
595+
result = result.getJSONObject(childKey);
596+
//
597+
boolean success = JSONResponse.isSuccess(result);
598+
int count = result == null ? null : result.getIntValue(JSONResponse.KEY_COUNT);
599+
600+
if (success == false || count != 1) { //如果 code = 200 但 count != 1,不能算成功,掩盖了错误为不好排查问题
601+
throw new ServerException("批量新增/修改失败!" + key + "/" + i + ":" + (success ? "成功但 count != 1 !" : (result == null ? "null" : result.getString(JSONResponse.KEY_MSG))));
602+
}
603+
604+
allCount += count;
605+
ids.add(result.get(JSONResponse.KEY_ID));
606+
}
607+
608+
JSONObject allResult = AbstractParser.newSuccessResult();
609+
allResult.put(JSONResponse.KEY_ID_IN, ids);
610+
allResult.put(JSONResponse.KEY_COUNT, allCount);
611+
612+
response.put(key, allResult); //不按原样返回,避免数据量过大
613+
}
614+
615+
600616
@Override
601617
public JSONObject parseResponse(RequestMethod method, String table, String alias, JSONObject request, List<Join> joinList, boolean isProcedure) throws Exception {
602618
SQLConfig config = newSQLConfig(method, table, alias, request, joinList, isProcedure);

APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/ObjectParser.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,20 @@ public interface ObjectParser {
8282
Object onReferenceParse(@NotNull String path);
8383

8484
//TODO 改用 MySQL json_add,json_remove,json_contains 等函数!
85-
/**PUT key:[]
85+
/**修改数组 PUT key:[]
8686
* @param key
8787
* @param array
8888
* @throws Exception
8989
*/
9090
void onPUTArrayParse(@NotNull String key, @NotNull JSONArray array) throws Exception;
9191

92+
/**批量新增或修改 POST or PUT Table[]:[{}]
93+
* @param key
94+
* @param array
95+
* @throws Exception
96+
*/
97+
void onTableArrayParse(@NotNull String key, @NotNull JSONArray array) throws Exception;
98+
9299
/**SQL 配置,for single object
93100
* @return {@link #setSQLConfig(int, int, int)}
94101
* @throws Exception
@@ -161,5 +168,4 @@ public interface ObjectParser {
161168
Map<String, Map<String, String>> getFunctionMap();
162169
Map<String, JSONObject> getChildMap();
163170

164-
165171
}

APIJSON-Java-Server/APIJSONORM/src/main/java/apijson/server/Operation.java

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,60 +14,106 @@
1414

1515
package apijson.server;
1616

17-
import apijson.StringUtil;
18-
1917
/**对请求JSON的操作
2018
* @author Lemon
2119
*/
2220
public enum Operation {
2321

2422
/**
25-
* 不允许传的字段
23+
* 不允许传的字段,结构是
24+
* "key0,key1,key2..."
2625
*/
2726
DISALLOW,
27+
2828
/**
29-
* 必须传的字段
29+
* 必须传的字段,结构是
30+
* "key0,key1,key2..."
3031
*/
3132
NECESSARY,
3233

33-
/**
34+
35+
/**TODO 是否应该把数组类型写成 BOOLEANS, NUMBERS 等复数单词,以便抽取 enum ?扩展用 VERIFY 或 INSERT/UPDATE 远程函数等
3436
* 验证是否符合预设的类型:
35-
* Boolean, Long, Double, String, Object, Array //目前在业务表中还用不上,单一的类型校验已经够用 , JSON(包括 {Object}, [Array], "{Object}", "Array")
37+
* BOOLEAN, NUMBER, DECIMAL, STRING, URL, DATE, TIME, DATETIME, OBJECT, ARRAY ]
38+
* 或它们的数组
39+
* BOOLEAN[], NUMBER[], DECIMAL[], STRING[], URL[], DATE[], TIME[], DATETIME[], OBJECT[], ARRAY[]
40+
* 结构是
41+
* {
42+
* key0: value0,
43+
* key1: value1,
44+
* key2: value2
45+
* ...
46+
* }
47+
* 例如
48+
* {
49+
* "id": "NUMBER", //id 类型必须为 NUMBER
50+
* "pictureList": "URL[]", //pictureList 类型必须为 URL[]
51+
* }
52+
* @see {@link Structure#type(String, String, Object, boolean)}
3653
*/
3754
TYPE,
55+
3856
/**
39-
* 验证是否符合预设的条件
57+
* 验证是否符合预设的条件,结构是
58+
* {
59+
* key0: value0,
60+
* key1: value1,
61+
* key2: value2
62+
* ...
63+
* }
64+
* 例如
65+
* {
66+
* "phone~": "PHONE", //phone 必须满足 PHONE 的格式
67+
* "status{}": [1,2,3], //status 必须在给出的范围内
68+
* "balance&{}":">0,<=10000" //必须满足 balance>0 & balance<=10000
69+
* }
4070
*/
4171
VERIFY,
72+
4273
/**
43-
* 验证是否不存在,除了本身的记录
74+
* 验证是否不存在,除了本身的记录,结构是
75+
* "key0,key1,key2..."
4476
*/
4577
UNIQUE,
4678

79+
4780
/**
48-
* 添加,当要被添加的对象不存在时
81+
* 添加,当要被添加的对象不存在时,结构是
82+
* {
83+
* key0: value0,
84+
* key1: value1,
85+
* key2: value2
86+
* ...
87+
* }
4988
*/
5089
INSERT,
90+
5191
/**
52-
* 强行放入,不存在时就添加,存在时就修改
92+
* 强行放入,不存在时就添加,存在时就修改,结构是
93+
* {
94+
* key0: value0,
95+
* key1: value1,
96+
* key2: value2
97+
* ...
98+
* }
5399
*/
54100
UPDATE,
101+
55102
/**
56-
* 替换,当要被替换的对象存在时
103+
* 替换,当要被替换的对象存在时,结构是
104+
* {
105+
* key0: value0,
106+
* key1: value1,
107+
* key2: value2
108+
* ...
109+
* }
57110
*/
58111
REPLACE,
112+
59113
/**
60-
* 移除,当要被移除的对象存在时
114+
* 移除,当要被移除的对象存在时,结构是
115+
* "key0,key1,key2..."
61116
*/
62117
REMOVE;
63118

64-
public static Operation get(String name) {
65-
try {//Enum.valueOf只要找不到对应的值就会抛异常
66-
return Operation.valueOf(StringUtil.toUpperCase(name));
67-
} catch (Exception e) {
68-
//empty
69-
}
70-
return null;
71-
}
72-
73119
}

0 commit comments

Comments
 (0)