Skip to content

Commit 83eeaa2

Browse files
committed
新增对允许但容易导致潜在问题的情况在 DEBUG 下返回警告信息
1 parent 214bbea commit 83eeaa2

File tree

3 files changed

+210
-71
lines changed

3 files changed

+210
-71
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,12 +833,39 @@ public JSONObject parseResponse(SQLConfig config, boolean isProcedure) throws Ex
833833
if (parser.getSQLExecutor() == null) {
834834
parser.createSQLExecutor();
835835
}
836+
if (parser != null && config.getParser() == null) {
837+
config.setParser(parser);
838+
}
836839
return parser.getSQLExecutor().execute(config, isProcedure);
837840
}
838841

839842

840843
@Override
841844
public SQLConfig newSQLConfig(boolean isProcedure) throws Exception {
845+
String raw = Log.DEBUG == false || sqlRequest == null ? null : sqlRequest.getString(apijson.JSONRequest.KEY_RAW);
846+
String[] keys = raw == null ? null : StringUtil.split(raw);
847+
if (keys != null && keys.length > 0) {
848+
boolean allow = AbstractSQLConfig.ALLOW_MISSING_KEY_4_COMBINE;
849+
850+
for (String key : keys) {
851+
if (sqlRequest.get(key) != null) {
852+
continue;
853+
}
854+
855+
String msg = "@raw:value 的 value 中 " + key + " 不合法!对应的 "
856+
+ key + ": value 在当前对象 " + name + " 不存在或 value = null,无法有效转为原始 SQL 片段!";
857+
858+
if (allow == false) {
859+
throw new UnsupportedOperationException(msg);
860+
}
861+
862+
if (parser instanceof AbstractParser) {
863+
((AbstractParser) parser).putWarnIfNeed(JSONRequest.KEY_RAW, msg);
864+
}
865+
break;
866+
}
867+
}
868+
842869
return newSQLConfig(method, table, alias, sqlRequest, joinList, isProcedure)
843870
.setParser(parser)
844871
.setObjectParser(this);

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

Lines changed: 147 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,10 @@ public AbstractParser() {
121121
* @param method null ? requestMethod = GET
122122
*/
123123
public AbstractParser(RequestMethod method) {
124-
super();
125-
setMethod(method);
126-
setNeedVerifyRole(AbstractVerifier.ENABLE_VERIFY_ROLE);
127-
setNeedVerifyContent(AbstractVerifier.ENABLE_VERIFY_CONTENT);
124+
super();
125+
setMethod(method);
126+
setNeedVerifyRole(AbstractVerifier.ENABLE_VERIFY_ROLE);
127+
setNeedVerifyContent(AbstractVerifier.ENABLE_VERIFY_CONTENT);
128128
}
129129
/**
130130
* @param method null ? requestMethod = GET
@@ -145,6 +145,57 @@ public AbstractParser<T> setRoot(boolean isRoot) {
145145
return this;
146146
}
147147

148+
public static final String KEY_REF = "Reference";
149+
150+
/**警告信息
151+
* Map<"Reference", "引用赋值获取路径 /Comment/userId 对应的值为 null!">
152+
*/
153+
protected Map<String, String> warnMap = new LinkedHashMap<>();
154+
public String getWarn(String type) {
155+
return warnMap == null ? null : warnMap.get(type);
156+
}
157+
public AbstractParser<T> putWarnIfNeed(String type, String warn) {
158+
if (Log.DEBUG) {
159+
String w = getWarn(type);
160+
if (StringUtil.isEmpty(w, true)) {
161+
putWarn(type, warn);
162+
}
163+
}
164+
return this;
165+
}
166+
public AbstractParser<T> putWarn(String type, String warn) {
167+
if (warnMap == null) {
168+
warnMap = new LinkedHashMap<>();
169+
}
170+
warnMap.put(type, warn);
171+
return this;
172+
}
173+
/**获取警告信息
174+
* @return
175+
*/
176+
public String getWarnString() {
177+
Set<Entry<String, String>> set = warnMap == null ? null : warnMap.entrySet();
178+
if (set == null || set.isEmpty()) {
179+
return null;
180+
}
181+
182+
StringBuilder sb = new StringBuilder();
183+
for (Entry<String, String> e : set) {
184+
String k = e == null ? null : e.getKey();
185+
String v = k == null ? null : e.getValue();
186+
if (StringUtil.isEmpty(v, true)) {
187+
continue;
188+
}
189+
190+
if (StringUtil.isNotEmpty(k, true)) {
191+
sb.append("[" + k + "]: ");
192+
}
193+
sb.append(v + "; ");
194+
}
195+
196+
return sb.toString();
197+
}
198+
148199

149200
@NotNull
150201
protected Visitor<T> visitor;
@@ -334,9 +385,6 @@ public AbstractParser<T> setNeedVerifyContent(boolean needVerifyContent) {
334385
}
335386

336387

337-
338-
339-
340388
protected SQLExecutor sqlExecutor;
341389
protected Verifier<T> verifier;
342390
protected Map<String, Object> queryResultMap;//path-result
@@ -487,7 +535,9 @@ public JSONObject parseResponse(JSONObject request) {
487535
onRollback();
488536
}
489537

490-
requestObject = error == null ? extendSuccessResult(requestObject, isRoot) : extendErrorResult(requestObject, error, requestMethod, getRequestURL(), isRoot);
538+
String warn = Log.DEBUG == false || error != null ? null : getWarnString();
539+
540+
requestObject = error == null ? extendSuccessResult(requestObject, warn, isRoot) : extendErrorResult(requestObject, error, requestMethod, getRequestURL(), isRoot);
491541

492542
JSONObject res = (globalFormat != null && globalFormat) && JSONResponse.isSuccess(requestObject) ? new JSONResponse(requestObject) : requestObject;
493543

@@ -663,31 +713,49 @@ else if (target.containsKey(key) == false) {
663713
* @return
664714
*/
665715
public static JSONObject newResult(int code, String msg) {
666-
return newResult(code, msg, false);
716+
return newResult(code, msg, null);
667717
}
668-
/**新建带状态内容的JSONObject
718+
719+
/**
720+
* 添加JSONObject的状态内容,一般用于错误提示结果
721+
*
669722
* @param code
670723
* @param msg
724+
* @param warn
725+
* @return
726+
*/
727+
public static JSONObject newResult(int code, String msg, String warn) {
728+
return newResult(code, msg, warn, false);
729+
}
730+
731+
/**
732+
* 新建带状态内容的JSONObject
733+
*
734+
* @param code
735+
* @param msg
736+
* @param warn
671737
* @param isRoot
672738
* @return
673739
*/
674-
public static JSONObject newResult(int code, String msg, boolean isRoot) {
675-
return extendResult(null, code, msg, isRoot);
740+
public static JSONObject newResult(int code, String msg, String warn, boolean isRoot) {
741+
return extendResult(null, code, msg, warn, isRoot);
676742
}
677743

678-
/**添加JSONObject的状态内容,一般用于错误提示结果
744+
/**
745+
* 添加JSONObject的状态内容,一般用于错误提示结果
746+
*
679747
* @param object
680748
* @param code
681749
* @param msg
682750
* @return
683751
*/
684-
public static JSONObject extendResult(JSONObject object, int code, String msg, boolean isRoot) {
752+
public static JSONObject extendResult(JSONObject object, int code, String msg, String warn, boolean isRoot) {
685753
int index = Log.DEBUG == false || isRoot == false || msg == null ? -1 : msg.lastIndexOf(Log.KEY_SYSTEM_INFO_DIVIDER);
686754
String debug = Log.DEBUG == false || isRoot == false ? null : (index >= 0 ? msg.substring(index + Log.KEY_SYSTEM_INFO_DIVIDER.length()).trim()
687755
: " \n提 bug 请发请求和响应的【完整截屏】,没图的自行解决!"
688-
+ " \n开发者有限的时间和精力主要放在【维护项目源码和文档】上!"
689-
+ " \n【描述不详细】 或 【文档/常见问题 已有答案】 的问题可能会被忽略!!"
690-
+ " \n【态度 不文明/不友善】的可能会被踢出群,问题也可能不予解答!!!"
756+
+ " \n开发者有限的时间和精力主要放在【维护项目源码和文档】上!"
757+
+ " \n【描述不详细】 或 【文档/常见问题 已有答案】 的问题可能会被忽略!!"
758+
+ " \n【态度 不文明/不友善】的可能会被踢出群,问题也可能不予解答!!!"
691759
+ " \n\n **环境信息** "
692760
+ " \n系统: " + Log.OS_NAME + " " + Log.OS_VERSION
693761
+ " \n数据库: DEFAULT_DATABASE = " + AbstractSQLConfig.DEFAULT_DATABASE
@@ -717,40 +785,61 @@ public static JSONObject extendResult(JSONObject object, int code, String msg, b
717785

718786
object.put(JSONResponse.KEY_MSG, msg);
719787
if (debug != null) {
788+
if (StringUtil.isNotEmpty(warn, true)) {
789+
debug += "\n 【警告】:" + warn;
790+
}
720791
object.put("debug:info|help", debug);
721792
}
722793

723794
return object;
724795
}
725796

726797

727-
/**添加请求成功的状态内容
798+
/**
799+
* 添加请求成功的状态内容
800+
*
728801
* @param object
729802
* @return
730803
*/
731804
public static JSONObject extendSuccessResult(JSONObject object) {
732805
return extendSuccessResult(object, false);
733806
}
807+
808+
public static JSONObject extendSuccessResult(JSONObject object, boolean isRoot) {
809+
return extendSuccessResult(object, null, isRoot);
810+
}
811+
734812
/**添加请求成功的状态内容
735813
* @param object
736814
* @param isRoot
737815
* @return
738816
*/
739-
public static JSONObject extendSuccessResult(JSONObject object, boolean isRoot) {
740-
return extendResult(object, JSONResponse.CODE_SUCCESS, JSONResponse.MSG_SUCCEED, isRoot);
817+
public static JSONObject extendSuccessResult(JSONObject object, String warn, boolean isRoot) {
818+
return extendResult(object, JSONResponse.CODE_SUCCESS, JSONResponse.MSG_SUCCEED, warn, isRoot);
741819
}
820+
742821
/**获取请求成功的状态内容
743822
* @return
744823
*/
745824
public static JSONObject newSuccessResult() {
746-
return newSuccessResult(false);
825+
return newSuccessResult(null);
747826
}
827+
748828
/**获取请求成功的状态内容
829+
* @param warn
830+
* @return
831+
*/
832+
public static JSONObject newSuccessResult(String warn) {
833+
return newSuccessResult(warn, false);
834+
}
835+
836+
/**获取请求成功的状态内容
837+
* @param warn
749838
* @param isRoot
750839
* @return
751840
*/
752-
public static JSONObject newSuccessResult(boolean isRoot) {
753-
return newResult(JSONResponse.CODE_SUCCESS, JSONResponse.MSG_SUCCEED, isRoot);
841+
public static JSONObject newSuccessResult(String warn, boolean isRoot) {
842+
return newResult(JSONResponse.CODE_SUCCESS, JSONResponse.MSG_SUCCEED, warn, isRoot);
754843
}
755844

756845
/**添加请求成功的状态内容
@@ -848,7 +937,7 @@ public static JSONObject extendErrorResult(JSONObject object, Throwable e, Reque
848937
}
849938

850939
int code = CommonException.getCode(e);
851-
return extendResult(object, code, msg, isRoot);
940+
return extendResult(object, code, msg, null, isRoot);
852941
}
853942

854943
/**新建错误状态内容
@@ -872,16 +961,13 @@ public static JSONObject newErrorResult(Exception e, boolean isRoot) {
872961
String msg = CommonException.getMsg(e);
873962
Integer code = CommonException.getCode(e);
874963

875-
return newResult(code, msg, isRoot);
964+
return newResult(code, msg, null, isRoot);
876965
}
877966

878-
return newResult(JSONResponse.CODE_SERVER_ERROR, JSONResponse.MSG_SERVER_ERROR, isRoot);
967+
return newResult(JSONResponse.CODE_SERVER_ERROR, JSONResponse.MSG_SERVER_ERROR, null, isRoot);
879968
}
880969

881970

882-
883-
884-
//TODO 启动时一次性加载Request所有内容,作为初始化。
885971
/**获取正确的请求,非GET请求必须是服务器指定的
886972
* @return
887973
* @throws Exception
@@ -902,7 +988,6 @@ public JSONObject parseCorrectRequest() throws Exception {
902988
*/
903989
@Override
904990
public JSONObject getStructure(@NotNull String table, String method, String tag, int version) throws Exception {
905-
// TODO 目前只使用 Request 而不使用 Response,所以这里写死用 REQUEST_MAP,以后可能 Response 表也会与 Request 表合并,用字段来区分
906991
String cacheKey = AbstractVerifier.getCacheKeyForRequest(method, tag);
907992
SortedMap<Integer, JSONObject> versionedMap = AbstractVerifier.REQUEST_MAP.get(cacheKey);
908993

@@ -1419,17 +1504,17 @@ else if (join != null){
14191504

14201505
index = path.lastIndexOf("/");
14211506
String tableKey = index < 0 ? path : path.substring(0, index); // User:owner
1422-
int index2 = tableKey.lastIndexOf("/");
1423-
String arrKey = index2 < 0 ? null : tableKey.substring(0, index2);
1424-
if (arrKey != null && JSONRequest.isArrayKey(arrKey) == false) {
1507+
int index2 = tableKey.lastIndexOf("/");
1508+
String arrKey = index2 < 0 ? null : tableKey.substring(0, index2);
1509+
if (arrKey != null && JSONRequest.isArrayKey(arrKey) == false) {
14251510
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + " 不是合法的数组 key[] !" +
1426-
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
1427-
}
1511+
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
1512+
}
14281513

1429-
tableKey = index2 < 0 ? tableKey : tableKey.substring(index2+1);
1514+
tableKey = index2 < 0 ? tableKey : tableKey.substring(index2+1);
14301515

1431-
apijson.orm.Entry<String, String> entry = Pair.parseEntry(tableKey, true);
1432-
String table = entry.getKey(); // User
1516+
apijson.orm.Entry<String, String> entry = Pair.parseEntry(tableKey, true);
1517+
String table = entry.getKey(); // User
14331518
if (StringUtil.isName(table) == false) {
14341519
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":value 中 value 的 Table 值 " + table + " 不合法!"
14351520
+ "必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!"
@@ -1458,20 +1543,20 @@ else if (join != null){
14581543
"必须是 {} 这种 JSONObject 格式!" + e2.getMessage());
14591544
}
14601545

1461-
if (arrKey != null) {
1462-
if (parentPathObj.get(JSONRequest.KEY_JOIN) != null) {
1463-
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ join: value } 中 value 不合法!" +
1464-
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
1465-
}
1546+
if (arrKey != null) {
1547+
if (parentPathObj.get(JSONRequest.KEY_JOIN) != null) {
1548+
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ join: value } 中 value 不合法!" +
1549+
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
1550+
}
14661551

1467-
Integer subPage = parentPathObj.getInteger(JSONRequest.KEY_PAGE);
1468-
if (subPage != null && subPage != 0) {
1469-
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ page: value } 中 value 不合法!" +
1470-
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中 page 值只能为 null 或 0 !");
1552+
Integer subPage = parentPathObj.getInteger(JSONRequest.KEY_PAGE);
1553+
if (subPage != null && subPage != 0) {
1554+
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ page: value } 中 value 不合法!" +
1555+
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中 page 值只能为 null 或 0 !");
1556+
}
14711557
}
1472-
}
14731558

1474-
boolean isAppJoin = "@".equals(joinType);
1559+
boolean isAppJoin = "@".equals(joinType);
14751560

14761561
JSONObject refObj = new JSONObject(tableObj.size(), true);
14771562

@@ -1489,8 +1574,8 @@ else if (join != null){
14891574
}
14901575

14911576
if (isAppJoin && StringUtil.isName(key.substring(0, key.length() - 1)) == false) {
1492-
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + key + " 不合法 !" +
1493-
"@ APP JOIN 只允许 key@:/Table/refKey 这种 = 等价连接!");
1577+
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + key + " 不合法 !" +
1578+
"@ APP JOIN 只允许 key@:/Table/refKey 这种 = 等价连接!");
14941579
}
14951580

14961581
refObj.put(key, tableObj.getString(key));
@@ -1525,20 +1610,20 @@ else if (join != null){
15251610
apijson.orm.Entry<String, String> te = tk == null || p.substring(ind2 + 1).indexOf("/") >= 0 ? null : Pair.parseEntry(tk, true);
15261611

15271612
if (te != null && JSONRequest.isTableKey(te.getKey()) && request.get(tk) instanceof JSONObject) {
1528-
if (isAppJoin) {
1529-
if (refObj.size() >= 1) {
1530-
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + k + " 不合法!"
1531-
+ "@ APP JOIN 必须有且只有一个引用赋值键值对!");
1532-
}
1613+
if (isAppJoin) {
1614+
if (refObj.size() >= 1) {
1615+
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + k + " 不合法!"
1616+
+ "@ APP JOIN 必须有且只有一个引用赋值键值对!");
1617+
}
15331618

1534-
if (StringUtil.isName(k.substring(0, k.length() - 1)) == false) {
1535-
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + k + " 不合法 !" +
1536-
"@ APP JOIN 只允许 key@:/Table/refKey 这种 = 等价连接!");
1619+
if (StringUtil.isName(k.substring(0, k.length() - 1)) == false) {
1620+
throw new IllegalArgumentException(JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + k + " 不合法 !" +
1621+
"@ APP JOIN 只允许 key@:/Table/refKey 这种 = 等价连接!");
1622+
}
15371623
}
1538-
}
15391624

1540-
refObj.put(k, v);
1541-
continue;
1625+
refObj.put(k, v);
1626+
continue;
15421627
}
15431628
}
15441629

0 commit comments

Comments
 (0)