解决高并发情况下参数校验规则可能因为执行过程 remove 了部分操作关键词导致校验出错

This commit is contained in:
TommyLemon 2021-01-17 01:54:03 +08:00
parent 1f529277fa
commit 8fd88e0af6

View File

@ -82,6 +82,9 @@ public abstract class AbstractVerifier<T> implements Verifier<T>, IdCallback {
private static final String TAG = "AbstractVerifier";
// 共享 STRUCTURE_MAP 则不能 remove 等做任何变更否则在并发情况下可能会出错加锁效率又低所以这里改为忽略对应的 key
public static final List<String> OPERATION_KEY_LIST;
// <TableName, <METHOD, allowRoles>>
// <User, <GET, [OWNER, ADMIN]>>
@NotNull
@ -97,6 +100,21 @@ public abstract class AbstractVerifier<T> implements Verifier<T>, IdCallback {
@NotNull
public static final Map<String, Pattern> COMPILE_MAP;
static {
OPERATION_KEY_LIST = new ArrayList<>();
OPERATION_KEY_LIST.add(TYPE.name());
OPERATION_KEY_LIST.add(VERIFY.name());
OPERATION_KEY_LIST.add(INSERT.name());
OPERATION_KEY_LIST.add(UPDATE.name());
OPERATION_KEY_LIST.add(REPLACE.name());
OPERATION_KEY_LIST.add(EXIST.name());
OPERATION_KEY_LIST.add(UNIQUE.name());
OPERATION_KEY_LIST.add(REMOVE.name());
OPERATION_KEY_LIST.add(MUST.name());
OPERATION_KEY_LIST.add(REFUSE.name());
OPERATION_KEY_LIST.add(NECESSARY.name());
OPERATION_KEY_LIST.add(DISALLOW.name());
SYSTEM_ACCESS_MAP = new HashMap<String, Map<RequestMethod, RequestRole[]>>();
SYSTEM_ACCESS_MAP.put(Access.class.getSimpleName(), getAccessMap(Access.class.getAnnotation(MethodAccess.class)));
@ -742,7 +760,7 @@ public abstract class AbstractVerifier<T> implements Verifier<T>, IdCallback {
return null;
}
//获取配置<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 获取配置<<<<<<<<<<<<<<<<<<<<<<<<<<<<
JSONObject type = target.getJSONObject(TYPE.name());
JSONObject verify = target.getJSONObject(VERIFY.name());
JSONObject insert = target.getJSONObject(INSERT.name());
@ -757,37 +775,21 @@ public abstract class AbstractVerifier<T> implements Verifier<T>, IdCallback {
String necessary = StringUtil.getNoBlankString(target.getString(NECESSARY.name()));
String disallow = StringUtil.getNoBlankString(target.getString(DISALLOW.name()));
target.remove(TYPE.name());
target.remove(VERIFY.name());
target.remove(INSERT.name());
target.remove(UPDATE.name());
target.remove(REPLACE.name());
target.remove(EXIST.name());
target.remove(UNIQUE.name());
target.remove(REMOVE.name());
target.remove(MUST.name());
target.remove(REFUSE.name());
target.remove(NECESSARY.name());
target.remove(DISALLOW.name());
try { // 避免中间抛异常导致 target put remove 掉的键值对
//移除字段<<<<<<<<<<<<<<<<<<<
// 移除字段<<<<<<<<<<<<<<<<<<<
String[] removes = StringUtil.split(remove);
if (removes != null && removes.length > 0) {
for (String r : removes) {
real.remove(r);
}
}
//移除字段>>>>>>>>>>>>>>>>>>>
// 移除字段>>>>>>>>>>>>>>>>>>>
//判断必要字段是否都有<<<<<<<<<<<<<<<<<<<
// 判断必要字段是否都有<<<<<<<<<<<<<<<<<<<
String[] musts = StringUtil.split(must);
List<String> mustList = musts == null ? new ArrayList<String>() : Arrays.asList(musts);
for (String s : mustList) {
if (real.get(s) == null) {//可能传null进来这里还会通过 real.containsKey(s) == false) {
if (real.get(s) == null) { // 可能传null进来这里还会通过 real.containsKey(s) == false) {
throw new IllegalArgumentException(method + "请求," + name
+ " 里面不能缺少 " + s + " 等[" + must + "]内的任何字段!");
}
@ -816,7 +818,7 @@ public abstract class AbstractVerifier<T> implements Verifier<T>, IdCallback {
Object rvalue;
for (Entry<String, Object> entry : set) {
key = entry == null ? null : entry.getKey();
if (key == null) {
if (key == null || OPERATION_KEY_LIST.contains(key)) {
continue;
}
tvalue = entry.getValue();
@ -971,24 +973,6 @@ public abstract class AbstractVerifier<T> implements Verifier<T>, IdCallback {
}
//校验重复>>>>>>>>>>>>>>>>>>>
}
finally {
//还原 <<<<<<<<<<
target.put(TYPE.name(), type);
target.put(VERIFY.name(), verify);
target.put(INSERT.name(), insert);
target.put(UPDATE.name(), update);
target.put(REPLACE.name(), replace);
target.put(EXIST.name(), exist);
target.put(UNIQUE.name(), unique);
target.put(REMOVE.name(), remove);
target.put(MUST.name(), must);
target.put(REFUSE.name(), refuse);
target.put(NECESSARY.name(), necessary);
target.put(DISALLOW.name(), disallow);
//还原 >>>>>>>>>>
}
Log.i(TAG, "parse return real = " + JSON.toJSONString(real));
return real;
@ -1019,9 +1003,10 @@ public abstract class AbstractVerifier<T> implements Verifier<T>, IdCallback {
for (Entry<String, Object> e : set) {
tk = e == null ? null : e.getKey();
if (tk == null) {
if (tk == null || OPERATION_KEY_LIST.contains(tk)) {
continue;
}
tv = e.getValue();
if (opt == TYPE) {