Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一个json支持多种操作, 独立url method #485

Merged
merged 4 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion APIJSONORM/src/main/java/apijson/RequestMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,17 @@ public enum RequestMethod {
*/
PUT,

/**
* json包含多条语句,支持增删改查,函数调用
*/
CRUD,

/**
* 删除数据
*/
DELETE;

public static final RequestMethod[] ALL = new RequestMethod[]{ GET, HEAD, GETS, HEADS, POST, PUT, DELETE};
public static final RequestMethod[] ALL = new RequestMethod[]{ GET, HEAD, GETS, HEADS, POST, PUT, CRUD, DELETE};

/**是否为GET请求方法
* @param method
Expand Down
15 changes: 11 additions & 4 deletions APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import static apijson.RequestMethod.POST;
import static apijson.RequestMethod.PUT;
import static apijson.orm.SQLConfig.TYPE_ITEM;

import static apijson.RequestMethod.GET;

/**简化Parser,getObject和getArray(getArrayConfig)都能用
* @author Lemon
Expand Down Expand Up @@ -254,7 +254,14 @@ public AbstractObjectParser parse(String name, boolean isReuse) throws Exception
continue;
}
String key = entry.getKey();


// 处理url crud, 将crud 转换为真实method
RequestMethod _method = this.parser.getRealMethod(method, key, value);
// 没有执行校验流程的情况,比如url head, sql@子查询, sql@ method=GET
if (key.endsWith("@") && request.get(key) instanceof JSONObject) {
request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, GET);
}

try {
boolean startsWithAt = key.startsWith("@");
//if (startsWithAt || (key.endsWith("()") == false)) {
Expand All @@ -275,11 +282,11 @@ else if (value instanceof JSONObject) { // JSONObject,往下一级提取
index ++;
}
}
else if ((method == POST || method == PUT) && value instanceof JSONArray
else if ((_method == POST || _method == PUT) && value instanceof JSONArray
&& JSONRequest.isTableArray(key)) { // JSONArray,批量新增或修改,往下一级提取
onTableArrayParse(key, (JSONArray) value);
}
else if (method == PUT && value instanceof JSONArray && (whereList == null || whereList.contains(key) == false)
else if (_method == PUT && value instanceof JSONArray && (whereList == null || whereList.contains(key) == false)
&& StringUtil.isName(key.replaceFirst("[+-]$", ""))) { // PUT JSONArray
onPUTArrayParse(key, (JSONArray) value);
}
Expand Down
77 changes: 50 additions & 27 deletions APIJSONORM/src/main/java/apijson/orm/AbstractParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import apijson.orm.exception.CommonException;

import static apijson.JSONObject.KEY_EXPLAIN;
import static apijson.RequestMethod.CRUD;
import static apijson.RequestMethod.GET;

/**parser for parsing request to JSONObject
Expand Down Expand Up @@ -2096,44 +2097,36 @@ private JSONObject batchVerify(RequestMethod method, String tag, int version, St
try {
if (key.startsWith("@")) {
try {
// 如果不匹配,不处理即可
// 如果不匹配,异常不处理即可
RequestMethod l_method = RequestMethod.valueOf(key.substring(1).toUpperCase());
if (l_method != null) {
if (request.get(key) instanceof JSONArray) {
for (Object objKey : request.getJSONArray(key)) {
key_method_Map.put(objKey, l_method);
}
continue;
} else {
throw new IllegalArgumentException("参数 " + key + " 必须是数组格式 ! ,例如: [\"Moment\", \"Comment[]\"]");
}
for(String objKey : StringUtil.split(request.getString(key))) {
key_method_Map.put(objKey, l_method);
}
} catch (Exception e) {
}
}

// 如果对象设置了@method, 优先使用 对象内部的@method
// 对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法
//
// 1、非crud,对于没有显式声明操作方法的,直接用 URL(/get, /post 等) 对应的默认操作方法
// 2、crud, 没有声明就用 GET
// 3、兼容 sql@ JSONObject,设置 GET方法
// 将method 设置到每个object, op执行会解析
if (request.get(key) instanceof JSONObject) {
if(request.getJSONObject(key).getString(apijson.JSONObject.KEY_METHOD) == null) {
if (key_method_Map.get(key) == null) {
// 数组会解析为对象进行校验,做一下兼容
if(key_method_Map.get(key + apijson.JSONObject.KEY_ARRAY) == null) {
if (key_method_Map.get(key) == null) {
// 数组会解析为对象进行校验,做一下兼容
if (key_method_Map.get(key + apijson.JSONObject.KEY_ARRAY) == null) {
if (method == RequestMethod.CRUD || (key.endsWith("@") && request.get(key) instanceof JSONObject)) {
request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, GET);
key_method_Map.put(key, GET);
} else {
request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, method);
}else {
request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, key_method_Map.get(key + apijson.JSONObject.KEY_ARRAY));
key_method_Map.put(key, method);
}
} else {
request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, key_method_Map.get(key));
request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, key_method_Map.get(key + apijson.JSONObject.KEY_ARRAY));
}
}

// get请求不校验
RequestMethod _method = RequestMethod.valueOf(request.getJSONObject(key).getString(apijson.JSONObject.KEY_METHOD).toUpperCase());
if (RequestMethod.isPublicMethod(_method)) {
jsonObject.put(key, request.getJSONObject(key));
continue;
} else {
request.getJSONObject(key).put(apijson.JSONObject.KEY_METHOD, key_method_Map.get(key));
}
}

Expand All @@ -2149,12 +2142,29 @@ private JSONObject batchVerify(RequestMethod method, String tag, int version, St
_method = RequestMethod.valueOf(request.getJSONObject(key).getString(apijson.JSONObject.KEY_METHOD).toUpperCase());
} else {
if (key_method_Map.get(key) == null) {
_method = method;
if (method == RequestMethod.CRUD) {
_method = GET;
key_method_Map.put(key, GET);
} else {
_method = method;
key_method_Map.put(key, method);
}
} else {
_method = key_method_Map.get(key);
}
}

// 非 CRUD 方法,都只能和 URL method 完全一致,避免意料之外的安全风险。
if (method != RequestMethod.CRUD && _method != method) {
throw new IllegalArgumentException("不支持在 " + method + " 中 " + _method + " !");
}

// get请求不校验
if (RequestMethod.isPublicMethod(_method)) {
jsonObject.put(key, request.get(key));
continue;
}

String _tag = buildTag(request, key);
JSONObject requestItem = new JSONObject();
requestItem.put(_tag, request.get(key));
Expand Down Expand Up @@ -2213,4 +2223,17 @@ protected JSONObject objectVerify(RequestMethod method, String tag, int version,
// JSONObject clone 浅拷贝没用,Structure.parse 会导致 structure 里面被清空,第二次从缓存里取到的就是 {}
return getVerifier().verifyRequest(method, name, target, request, maxUpdateCount, getGlobalDatabase(), getGlobalSchema(), creator);
}

/***
* 兼容url crud, 获取真实method
* @param method = crud
* @param key
* @return
*/
public RequestMethod getRealMethod(RequestMethod method, String key, Object value) {
if(method == CRUD && (value instanceof JSONObject || value instanceof JSONArray)) {
return this.key_method_Map.get(key);
}
return method;
}
}
8 changes: 4 additions & 4 deletions APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4208,14 +4208,14 @@ private static String buildWithAsExpreSql(@NotNull AbstractSQLConfig config, Str
if(config.withAsExpreSqlList != null && config.withAsExpreSqlList.size() > 0) {
String withAsExpreSql = "WITH ";
// 只有一条
if(config.withAsExpreSqlList.size() == 1) {
if (config.withAsExpreSqlList.size() == 1) {
withAsExpreSql += config.withAsExpreSqlList.get(0) + "\n" + cSql;
}else {
} else {
int lastIndex = config.withAsExpreSqlList.size() - 1;
for (int i = 0; i < config.withAsExpreSqlList.size(); i++) {
if(i == lastIndex) {
if (i == lastIndex) {
withAsExpreSql += config.withAsExpreSqlList.get(i) + "\n" + cSql;
}else {
} else {
withAsExpreSql += config.withAsExpreSqlList.get(i) + ",\n";
}
}
Expand Down
Loading