check child is json or not in zookeeper.it will be continue if not. (#14166)

* check child is json or not.it will be continue if not.

* try to save code format problem.

* child could be json array.so child could start with { or [.

* fix the problem of it will continue some message to make zookeeper outtime.

* try to continue the string without warn.

* format the code.

* catch the exception of JSONException.

* try to fix java.lang.NoClassDefFoundError because of JSONException.

* add isJson method and implement it in JSON.

* implement the checkJson method and use it in ZookeeperRegistry

* format the code.

* add some test case.

* format the code.

* format the code.

* format the code.

* format the code.

* format the code.

* format the code.

* format the code.

* format the code.

* format the code.

* add some information.

* format the code.

* add human friendly comment.

* format the code.

* format the code.

---------

Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
Co-authored-by: Jermaine Hua <crazyhzm@gmail.com>
This commit is contained in:
Lee hong 2024-05-21 11:36:53 +08:00 committed by GitHub
parent e21244a431
commit 189d76be5d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 103 additions and 1 deletions

View File

@ -23,6 +23,8 @@ import java.util.Map;
public interface JSON {
boolean isSupport();
boolean isJson(String json);
<T> T toJavaObject(String json, Type type);
<T> List<T> toJavaList(String json, Class<T> clazz);

View File

@ -19,9 +19,17 @@ package org.apache.dubbo.common.json.impl;
import java.lang.reflect.Type;
import java.util.List;
import com.alibaba.fastjson2.JSONValidator;
import com.alibaba.fastjson2.JSONWriter;
public class FastJson2Impl extends AbstractJSONImpl {
@Override
public boolean isJson(String json) {
JSONValidator validator = JSONValidator.from(json);
return validator.validate();
}
@Override
public <T> T toJavaObject(String json, Type type) {
return com.alibaba.fastjson2.JSON.parseObject(json, type);

View File

@ -23,6 +23,16 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
public class FastJsonImpl extends AbstractJSONImpl {
@Override
public boolean isJson(String json) {
try {
Object obj = com.alibaba.fastjson.JSON.parse(json);
return obj instanceof com.alibaba.fastjson.JSONObject || obj instanceof com.alibaba.fastjson.JSONArray;
} catch (com.alibaba.fastjson.JSONException e) {
return false;
}
}
@Override
public <T> T toJavaObject(String json, Type type) {
return com.alibaba.fastjson.JSON.parseObject(json, type);

View File

@ -20,12 +20,25 @@ import java.lang.reflect.Type;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
public class GsonImpl extends AbstractJSONImpl {
// weak reference of com.google.gson.Gson, prevent throw exception when init
private volatile Object gsonCache = null;
@Override
public boolean isJson(String json) {
try {
JsonElement jsonElement = JsonParser.parseString(json);
return jsonElement.isJsonObject() || jsonElement.isJsonArray();
} catch (JsonSyntaxException e) {
return false;
}
}
@Override
public <T> T toJavaObject(String json, Type type) {
return getGson().fromJson(json, type);

View File

@ -20,7 +20,9 @@ import java.lang.reflect.Type;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
@ -31,6 +33,16 @@ public class JacksonImpl extends AbstractJSONImpl {
private volatile Object jacksonCache = null;
@Override
public boolean isJson(String json) {
try {
JsonNode node = objectMapper.readTree(json);
return node.isObject() || node.isArray();
} catch (JsonProcessingException e) {
return false;
}
}
@Override
public <T> T toJavaObject(String json, Type type) {
try {

View File

@ -146,4 +146,8 @@ public class JsonUtils {
public static List<String> checkStringList(List<?> rawList) {
return getJson().checkStringList(rawList);
}
public static boolean checkJson(String json) {
return getJson().isJson(json);
}
}

View File

@ -63,6 +63,49 @@ class JsonUtilsTest {
}
}
@Test
void testIsJson() {
JsonUtils.setJson(null);
// prefer use fastjson2
System.setProperty("dubbo.json-framework.prefer", "fastjson2");
Assertions.assertTrue(
JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}"));
Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string"));
Assertions.assertTrue(
JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]"));
System.clearProperty("dubbo.json-framework.prefer");
// prefer use fastjson
JsonUtils.setJson(null);
System.setProperty("dubbo.json-framework.prefer", "fastjson");
Assertions.assertTrue(
JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}"));
Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string"));
Assertions.assertTrue(
JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]"));
System.clearProperty("dubbo.json-framework.prefer");
// prefer use gson
JsonUtils.setJson(null);
System.setProperty("dubbo.json-framework.prefer", "gson");
Assertions.assertTrue(
JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}"));
Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string"));
Assertions.assertTrue(
JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]"));
System.clearProperty("dubbo.json-framework.prefer");
// prefer use jackson
JsonUtils.setJson(null);
System.setProperty("dubbo.json-framework.prefer", "jackson");
Assertions.assertTrue(
JsonUtils.getJson().isJson("{\"title\":\"Java Programming\",\"author\":\"John Doe\",\"pages\":300}"));
Assertions.assertFalse(JsonUtils.getJson().isJson("This is not a JSON string"));
Assertions.assertTrue(
JsonUtils.getJson().isJson("[{\"title\":\"Java Programming\"}, {\"title\":\"Python Programming\"}]"));
System.clearProperty("dubbo.json-framework.prefer");
}
@Test
void testGetJson1() {
Assertions.assertNotNull(JsonUtils.getJson());

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.JsonUtils;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.support.CacheableFailbackRegistry;
@ -46,6 +47,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.CHECK_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_DESERIALIZE;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ZOOKEEPER_EXCEPTION;
import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.CONSUMERS_CATEGORY;
@ -201,7 +203,15 @@ public class ZookeeperRegistry extends CacheableFailbackRegistry {
ChildListener zkListener = ConcurrentHashMapUtils.computeIfAbsent(
listeners, listener, k -> (parentPath, currentChildren) -> {
for (String child : currentChildren) {
child = URL.decode(child);
try {
child = URL.decode(child);
if (!(JsonUtils.checkJson(child))) {
throw new Exception("dubbo-admin subscribe " + child + " failed,beacause "
+ child + "is root path in " + url);
}
} catch (Exception e) {
logger.warn(PROTOCOL_ERROR_DESERIALIZE, "", "", e.getMessage());
}
if (!anyServices.contains(child)) {
anyServices.add(child);
subscribe(