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:
parent
e21244a431
commit
189d76be5d
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue