From eccf2524669d390dcadd9ab1caaa07fab19330bb Mon Sep 17 00:00:00 2001 From: TommyLemon Date: Sun, 3 Sep 2023 03:52:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=90=8C=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=86=85=E5=A4=9A=E7=A7=8D=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=9A=84=E5=85=B3=E9=94=AE=E8=AF=8D=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81=20@post:=20"User",=20@gets?= =?UTF-8?q?:=20{=20"Privacy":=20"Privacy-phone"=20}=20=E7=AD=89=E7=AE=80?= =?UTF-8?q?=E5=8C=96=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/apijson/JSONObject.java | 28 +++- .../src/main/java/apijson/RequestMethod.java | 20 ++- .../main/java/apijson/orm/AbstractParser.java | 144 +++++++++++------- .../java/apijson/orm/AbstractSQLConfig.java | 78 +++++++--- 4 files changed, 184 insertions(+), 86 deletions(-) diff --git a/APIJSONORM/src/main/java/apijson/JSONObject.java b/APIJSONORM/src/main/java/apijson/JSONObject.java index a73203596..571c0aedf 100755 --- a/APIJSONORM/src/main/java/apijson/JSONObject.java +++ b/APIJSONORM/src/main/java/apijson/JSONObject.java @@ -6,6 +6,7 @@ package apijson; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -151,7 +152,16 @@ public JSONObject setUserIdIn(List list) { public static final String KEY_ORDER = "@order"; //排序方式 public static final String KEY_RAW = "@raw"; // 自定义原始 SQL 片段 public static final String KEY_JSON = "@json"; //SQL Server 把字段转为 JSON 输出 - public static final String KEY_METHOD = "@method"; //json对象配置操作方法 + public static final String KEY_METHOD = "@method"; // json 对象配置操作方法 + public static final String KEY_GET = "@get"; // json 对象配置操作方法 + public static final String KEY_GETS = "@gets"; // json 对象配置操作方法 + public static final String KEY_HEAD = "@head"; // json 对象配置操作方法 + public static final String KEY_HEADS = "@heads"; // json 对象配置操作方法 + public static final String KEY_POST = "@post"; // json 对象配置操作方法 + public static final String KEY_PUT = "@put"; // json 对象配置操作方法 + public static final String KEY_DELETE = "@delete"; // json 对象配置操作方法 + + public static final Map KEY_METHOD_ENUM_MAP; public static final List TABLE_KEY_LIST; static { @@ -174,6 +184,22 @@ public JSONObject setUserIdIn(List list) { TABLE_KEY_LIST.add(KEY_RAW); TABLE_KEY_LIST.add(KEY_JSON); TABLE_KEY_LIST.add(KEY_METHOD); + TABLE_KEY_LIST.add(KEY_GET); + TABLE_KEY_LIST.add(KEY_GETS); + TABLE_KEY_LIST.add(KEY_HEAD); + TABLE_KEY_LIST.add(KEY_HEADS); + TABLE_KEY_LIST.add(KEY_POST); + TABLE_KEY_LIST.add(KEY_PUT); + TABLE_KEY_LIST.add(KEY_DELETE); + + KEY_METHOD_ENUM_MAP = new LinkedHashMap<>(); + KEY_METHOD_ENUM_MAP.put(KEY_GET, RequestMethod.GET); + KEY_METHOD_ENUM_MAP.put(KEY_GETS, RequestMethod.GETS); + KEY_METHOD_ENUM_MAP.put(KEY_HEAD, RequestMethod.HEAD); + KEY_METHOD_ENUM_MAP.put(KEY_HEADS, RequestMethod.HEADS); + KEY_METHOD_ENUM_MAP.put(KEY_POST, RequestMethod.POST); + KEY_METHOD_ENUM_MAP.put(KEY_PUT, RequestMethod.PUT); + KEY_METHOD_ENUM_MAP.put(KEY_DELETE, RequestMethod.DELETE); } //@key关键字都放这个类 >>>>>>>>>>>>>>>>>>>>>> diff --git a/APIJSONORM/src/main/java/apijson/RequestMethod.java b/APIJSONORM/src/main/java/apijson/RequestMethod.java index 9e2f09bef..410775c1a 100755 --- a/APIJSONORM/src/main/java/apijson/RequestMethod.java +++ b/APIJSONORM/src/main/java/apijson/RequestMethod.java @@ -5,6 +5,9 @@ package apijson; +import java.util.Arrays; +import java.util.List; + /**请求方法,对应org.springframework.web.bind.annotation.RequestMethod,多出GETS,HEADS方法 * @author Lemon */ @@ -41,17 +44,20 @@ public enum RequestMethod { PUT, /** - * json包含多条语句,支持增删改查,函数调用 + * 删除数据 */ - CRUD, - + DELETE, + /** - * 删除数据 + * json 包含多条语句,支持增删改查、函数调用 */ - DELETE; - - public static final RequestMethod[] ALL = new RequestMethod[]{ GET, HEAD, GETS, HEADS, POST, PUT, CRUD, DELETE}; + CRUD; + public static final RequestMethod[] ALL = new RequestMethod[]{ GET, HEAD, GETS, HEADS, POST, PUT, DELETE, CRUD }; + public static final List ALL_NAME_LIST = Arrays.asList( + GET.name(), HEAD.name(), GETS.name(), HEADS.name(), POST.name(), PUT.name(), DELETE.name(), CRUD.name() + ); + /**是否为GET请求方法 * @param method * @param containPrivate 包含私密(非明文)获取方法GETS diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java index 685f1c8ac..c731b02c3 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java @@ -410,11 +410,12 @@ public JSONObject parseResponse(JSONObject request) { requestObject = request; try { setVersion(requestObject.getIntValue(JSONRequest.KEY_VERSION)); + requestObject.remove(JSONRequest.KEY_VERSION); + if (getMethod() != RequestMethod.CRUD) { setTag(requestObject.getString(JSONRequest.KEY_TAG)); requestObject.remove(JSONRequest.KEY_TAG); } - requestObject.remove(JSONRequest.KEY_VERSION); } catch (Exception e) { return extendErrorResult(requestObject, e, requestMethod, getRequestURL(), isRoot); } @@ -2089,7 +2090,7 @@ protected JSONObject getRequestStructure(RequestMethod method, String tag, int v } protected JSONObject batchVerify(RequestMethod method, String tag, int version, String name, @NotNull JSONObject request, int maxUpdateCount, SQLCreator creator) throws Exception { - JSONObject jsonObject = new JSONObject(true); + JSONObject correctRequest = new JSONObject(true); List removeTmpKeys = new ArrayList<>(); // 请求json里面的临时变量,不需要带入后面的业务中,比如 @post、@get等 Set reqSet = request == null ? null : request.keySet(); @@ -2098,49 +2099,82 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, } for (String key : reqSet) { - // key重复直接抛错(xxx:alias, xxx:alias[]) - if (jsonObject.containsKey(key) || jsonObject.containsKey(key + apijson.JSONObject.KEY_ARRAY)) { - throw new IllegalArgumentException("对象名重复,请添加别名区分 ! ,重复对象名为: " + key); + // key 重复直接抛错(xxx:alias, xxx:alias[]) + if (correctRequest.containsKey(key) || correctRequest.containsKey(key + apijson.JSONObject.KEY_ARRAY)) { + throw new IllegalArgumentException("对象名重复,请添加别名区分 ! 重复对象名为: " + key); } - // @post、@get等RequestMethod + // @post、@get 等 RequestMethod try { - if (key.startsWith("@") && getEnum(RequestMethod.class, key.substring(1).toUpperCase(), null) != null) { + RequestMethod keyMethod = apijson.orm.JSONRequest.KEY_METHOD_ENUM_MAP.get(key); + if (keyMethod != null) { // 如果不匹配,异常不处理即可 - RequestMethod _method = RequestMethod.valueOf(key.substring(1).toUpperCase()); removeTmpKeys.add(key); - JSONObject obj = request.getJSONObject(key); - Set set = obj == null ? new HashSet<>() : obj.keySet(); + Object val = request.get(key); + JSONObject obj = val instanceof JSONObject ? request.getJSONObject(key) : null; + if (obj == null) { + if (val instanceof String) { + String[] tbls = StringUtil.split((String) val); + if (tbls != null && tbls.length > 0) { + obj = new JSONObject(true); + for (int i = 0; i < tbls.length; i++) { + String tbl = tbls[i]; + if (obj.containsKey(tbl)) { + throw new ConflictException(key + ": value 中 " + tbl + " 已经存在,不能重复!"); + } + obj.put(tbl, new JSONObject(true)); + } + } + } + else { + throw new IllegalArgumentException(key + ": value 中 value 类型错误,只能是 String 或 JSONObject {} !"); + } + } + + Set> set = obj == null ? new HashSet<>() : obj.entrySet(); - for (String objKey : set) { + for (Entry objEntry : set) { + String objKey = objEntry == null ? null : objEntry.getKey(); if (objKey == null) { continue; } Map objAttrMap = new HashMap<>(); - objAttrMap.put(apijson.JSONObject.KEY_METHOD, _method); + objAttrMap.put(apijson.JSONObject.KEY_METHOD, keyMethod); keyObjectAttributesMap.put(objKey, objAttrMap); - JSONObject objAttrJson = obj.getJSONObject(objKey); - Set> objSet = objAttrJson == null ? new HashSet<>() : objAttrJson.entrySet(); - for (Entry entry : objSet) { - String objAttrKey = entry == null ? null : entry.getKey(); - if (objAttrKey == null) { - continue; + Object objVal = objEntry.getValue(); + JSONObject objAttrJson = objVal instanceof JSONObject ? obj.getJSONObject(objKey) : null; + if (objAttrJson == null) { + if (objVal instanceof String) { + objAttrMap.put(JSONRequest.KEY_TAG, objVal); } + else { + throw new IllegalArgumentException(key + ": { " + objKey + ": value 中 value 类型错误,只能是 String 或 JSONObject {} !"); + } + } + else { + Set> objSet = objAttrJson == null ? new HashSet<>() : objAttrJson.entrySet(); - switch (objAttrKey) { - case apijson.JSONObject.KEY_DATASOURCE: - case apijson.JSONObject.KEY_SCHEMA: - case apijson.JSONObject.KEY_DATABASE: - case JSONRequest.KEY_VERSION: - case apijson.JSONObject.KEY_ROLE: - case JSONRequest.KEY_TAG: - objAttrMap.put(objAttrKey, entry.getValue()); - break; - default: - break; + for (Entry entry : objSet) { + String objAttrKey = entry == null ? null : entry.getKey(); + if (objAttrKey == null) { + continue; + } + + switch (objAttrKey) { + case apijson.JSONObject.KEY_DATASOURCE: + case apijson.JSONObject.KEY_SCHEMA: + case apijson.JSONObject.KEY_DATABASE: + case JSONRequest.KEY_VERSION: + case apijson.JSONObject.KEY_ROLE: + case JSONRequest.KEY_TAG: + objAttrMap.put(objAttrKey, entry.getValue()); + break; + default: + break; + } } } } @@ -2189,15 +2223,17 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, } if (key.startsWith("@") || key.endsWith("@")) { - jsonObject.put(key, obj); + correctRequest.put(key, obj); continue; } if (obj instanceof JSONObject || obj instanceof JSONArray) { - RequestMethod _method = null; + RequestMethod _method; if (obj instanceof JSONObject) { - _method = RequestMethod.valueOf(request.getJSONObject(key).getString(apijson.JSONObject.KEY_METHOD).toUpperCase()); - String combine = request.getJSONObject(key).getString(KEY_COMBINE); + JSONObject tblObj = request.getJSONObject(key); + String mn = tblObj == null ? null : tblObj.getString(apijson.JSONObject.KEY_METHOD); + _method = mn == null ? null : RequestMethod.valueOf(mn); + String combine = _method == null ? null : tblObj.getString(KEY_COMBINE); if (combine != null && RequestMethod.isPublicMethod(_method) == false) { throw new IllegalArgumentException(key + ":{} 里的 @combine:value 不合法!开放请求 GET、HEAD 才允许传 @combine:value !"); } @@ -2207,22 +2243,14 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, if (attrMap == null) { if (method == RequestMethod.CRUD) { _method = GET; - if (attrMap == null) { - Map objAttrMap = new HashMap<>(); - objAttrMap.put(apijson.JSONObject.KEY_METHOD, GET); - keyObjectAttributesMap.put(key, objAttrMap); - } else { - attrMap.put(apijson.JSONObject.KEY_METHOD, GET); - } + Map objAttrMap = new HashMap<>(); + objAttrMap.put(apijson.JSONObject.KEY_METHOD, GET); + keyObjectAttributesMap.put(key, objAttrMap); } else { _method = method; - if (attrMap == null) { - Map objAttrMap = new HashMap<>(); - objAttrMap.put(apijson.JSONObject.KEY_METHOD, method); - keyObjectAttributesMap.put(key, objAttrMap); - } else { - attrMap.put(apijson.JSONObject.KEY_METHOD, method); - } + Map objAttrMap = new HashMap<>(); + objAttrMap.put(apijson.JSONObject.KEY_METHOD, method); + keyObjectAttributesMap.put(key, objAttrMap); } } else { _method = (RequestMethod) attrMap.get(apijson.JSONObject.KEY_METHOD); @@ -2236,29 +2264,29 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, // get请求不校验 if (RequestMethod.isPublicMethod(_method)) { - jsonObject.put(key, obj); + correctRequest.put(key, obj); continue; } - if(tag != null && !tag.contains(":")) { + if (tag != null && ! tag.contains(":")) { JSONObject object = getRequestStructure(_method, tag, version); JSONObject ret = objectVerify(_method, tag, version, name, request, maxUpdateCount, creator, object); - jsonObject.putAll(ret); + correctRequest.putAll(ret); break; } String _tag = buildTag(request, key, method, tag); JSONObject object = getRequestStructure(_method, _tag, version); - if(method == RequestMethod.CRUD && StringUtil.isEmpty(tag, true)) { + if (method == RequestMethod.CRUD && StringUtil.isEmpty(tag, true)) { JSONObject requestItem = new JSONObject(); requestItem.put(key, obj); JSONObject ret = objectVerify(_method, _tag, version, name, requestItem, maxUpdateCount, creator, object); - jsonObject.put(key, ret.get(key)); + correctRequest.put(key, ret.get(key)); } else { return objectVerify(_method, _tag, version, name, request, maxUpdateCount, creator, object); } } else { - jsonObject.put(key, obj); + correctRequest.put(key, obj); } } catch (Exception e) { e.printStackTrace(); @@ -2266,12 +2294,12 @@ protected JSONObject batchVerify(RequestMethod method, String tag, int version, } } - // 这里是requestObject ref request 的引用, 删除不需要的临时变量 + // 这里是 requestObject ref request 的引用, 删除不需要的临时变量 for (String removeKey : removeTmpKeys) { request.remove(removeKey); } - return jsonObject; + return correctRequest; } public static > E getEnum(final Class enumClass, final String enumName, final E defaultEnum) { @@ -2284,7 +2312,7 @@ public static > E getEnum(final Class enumClass, final Stri return defaultEnum; } } - + protected void setRequestAttribute(String key, boolean isArray, String attrKey, @NotNull JSONObject request) { Map attrMap = keyObjectAttributesMap.get(isArray ? key + apijson.JSONObject.KEY_ARRAY : key); Object attrVal = attrMap == null ? null : attrMap.get(attrKey); @@ -2308,7 +2336,7 @@ protected String buildTag(JSONObject request, String key, RequestMethod method, } return tag; } - + protected JSONObject objectVerify(RequestMethod method, String tag, int version, String name, @NotNull JSONObject request , int maxUpdateCount, SQLCreator creator, JSONObject object) throws Exception { @@ -2317,7 +2345,7 @@ 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 diff --git a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java index 9d6018378..eaf3bbf86 100755 --- a/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java +++ b/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java @@ -4901,8 +4901,8 @@ public static SQLConfig newSQLConfig(RequestMethod method, St throw new NullPointerException(TAG + ": newSQLConfig request == null!"); } - boolean explain = request.getBooleanValue(KEY_EXPLAIN); - if (explain && Log.DEBUG == false) { // 不在 config.setExplain 抛异常,一方面处理更早性能更好,另一方面为了内部调用可以绕过这个限制 + Boolean explain = request.getBoolean(KEY_EXPLAIN); + if (explain != null && explain && Log.DEBUG == false) { // 不在 config.setExplain 抛异常,一方面处理更早性能更好,另一方面为了内部调用可以绕过这个限制 throw new UnsupportedOperationException("非DEBUG模式, 不允许传 " + KEY_EXPLAIN + " !"); } @@ -5065,6 +5065,7 @@ else if (userId instanceof Subquery) {} String order = request.getString(KEY_ORDER); String raw = request.getString(KEY_RAW); String json = request.getString(KEY_JSON); + String mthd = request.getString(KEY_METHOD); try { // 强制作为条件且放在最前面优化性能 @@ -5547,7 +5548,7 @@ else if (newHaving != null) { // @having, @haivng& >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - config.setExplain(explain); + config.setExplain(explain != null && explain); config.setCache(getCache(cache)); config.setDistinct(distinct); config.setColumn(column == null ? null : cs); //解决总是 config.column != null,总是不能得到 * @@ -5587,23 +5588,60 @@ else if (newHaving != null) { } // 关键词 - request.put(KEY_DATABASE, database); - request.put(KEY_ROLE, role); - request.put(KEY_EXPLAIN, explain); - request.put(KEY_CACHE, cache); - request.put(KEY_DATASOURCE, datasource); - request.put(KEY_SCHEMA, schema); - request.put(KEY_FROM, from); - request.put(KEY_COLUMN, column); - request.put(KEY_NULL, nulls); - request.put(KEY_CAST, cast); - request.put(KEY_COMBINE, combine); - request.put(KEY_GROUP, group); - request.put(KEY_HAVING, having); - request.put(KEY_HAVING_AND, havingAnd); - request.put(KEY_ORDER, order); - request.put(KEY_RAW, raw); - request.put(KEY_JSON, json); + if (role != null) { + request.put(KEY_ROLE, role); + } + if (explain != null) { + request.put(KEY_EXPLAIN, explain); + } + if (cache != null) { + request.put(KEY_CACHE, cache); + } + if (database != null) { + request.put(KEY_DATABASE, database); + } + if (datasource != null) { + request.put(KEY_DATASOURCE, datasource); + } + if (schema != null) { + request.put(KEY_SCHEMA, schema); + } + if (from != null) { + request.put(KEY_FROM, from); + } + if (column != null) { + request.put(KEY_COLUMN, column); + } + if (nulls != null) { + request.put(KEY_NULL, nulls); + } + if (cast != null) { + request.put(KEY_CAST, cast); + } + if (combine != null) { + request.put(KEY_COMBINE, combine); + } + if (group != null) { + request.put(KEY_GROUP, group); + } + if (having != null) { + request.put(KEY_HAVING, having); + } + if (havingAnd != null) { + request.put(KEY_HAVING_AND, havingAnd); + } + if (order != null) { + request.put(KEY_ORDER, order); + } + if (raw != null) { + request.put(KEY_RAW, raw); + } + if (json != null) { + request.put(KEY_JSON, json); + } + if (mthd != null) { + request.put(KEY_METHOD, mthd); + } } return config;