如何使用GSON检查JSON在Java中是否有效?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用GSON检查JSON在Java中是否有效?相关的知识,希望对你有一定的参考价值。
我有方法必须检查JSON是否有效,在How to check whether a given string is valid JSON in Java上找到但它不起作用。
public static boolean isJson(String Json) {
Gson gson = new Gson();
try {
gson.fromJson(Json, Object.class);
return true;
} catch (com.google.gson.JsonSyntaxException ex) {
return false;
}
}
如果我将这个方法与一些字符串一起使用,它总是返回true。例如:
System.out.println(renderhtml.isJson("{"status": "UP"}"));
它给了我true
,和
System.out.println(renderHtml.isJson("bncjbhjfjhj"));
也给了我true
。
虽然这对你来说可能很奇怪
"bncjbhjfjhj"
确实是有效的json,因为它是一个字符串,它是唯一的字符串。
根据不那么新的JSON RFC
JSON文本是序列化值。请注意,某些先前的JSON规范将JSON文本约束为对象或数组。只生成调用JSON文本的对象或数组的实现将是可互操作的,因为所有实现都将接受这些作为符合JSON文本。
你不应该使用Gson
进行这样的验证:
Gson
是一个执行反序列化的对象,因此它将整个JSON反序列化为内存中的对象。Gson
,我不知道它,对于一些无效的JSON可能不是很严格:bncjbhjfjhj
被反序列化为java.lang.String
实例。惊喜,惊喜!
private static final Gson gson = new Gson();
private static final String VALID_JSON = "{"status": "UP"}";
private static final String INVALID_JSON = "bncjbhjfjhj";
System.out.println(gson.fromJson(VALID_JSON, Object.class).getClass());
System.out.println(gson.fromJson(INVALID_JSON, Object.class).getClass());
输出:
com.google.gson.internal.LinkedTreeMap类 class java.lang.String
你可以在这里做的是使用JsonReader
通过令牌读取传入的JSON令牌,从而使得给定的JSON文档在语法上是有效的。
private static boolean isJsonValid(final String json)
throws IOException {
return isJsonValid(new StringReader(json));
}
private static boolean isJsonValid(final Reader reader)
throws IOException {
return isJsonValid(new JsonReader(reader));
}
private static boolean isJsonValid(final JsonReader jsonReader)
throws IOException {
try {
JsonToken token;
loop:
while ( (token = jsonReader.peek()) != END_DOCUMENT && token != null ) {
switch ( token ) {
case BEGIN_ARRAY:
jsonReader.beginArray();
break;
case END_ARRAY:
jsonReader.endArray();
break;
case BEGIN_OBJECT:
jsonReader.beginObject();
break;
case END_OBJECT:
jsonReader.endObject();
break;
case NAME:
jsonReader.nextName();
break;
case STRING:
case NUMBER:
case BOOLEAN:
case NULL:
jsonReader.skipValue();
break;
case END_DOCUMENT:
break loop;
default:
throw new AssertionError(token);
}
}
return true;
} catch ( final MalformedJsonException ignored ) {
return false;
}
}
然后测试一下:
System.out.println(isJsonValid(VALID_JSON));
System.out.println(isJsonValid(INVALID_JSON));
输出:
真正 假
根据org.json
,我找到了解决方案,但使用了How to check whether a given string is valid JSON in Java库
public static boolean isJson(String Json) {
try {
new JSONObject(Json);
} catch (JSONException ex) {
try {
new JSONArray(Json);
} catch (JSONException ex1) {
return false;
}
}
return true;
}
现在随机看字符串bncjbhjfjhj
是false
和{"status": "UP"}
是真的。
另一种选择是将自定义的后检查应用到顶级json对象,如下所示:
import org.junit.Test;
import com.google.gson.*;
import static org.junit.Assert.*;
public class JsonTest {
private JsonObject parse(@Nonnull String json) throws JsonSyntaxException {
JsonElement res = new JsonParser().parse(json);
System.out.println(res);
if (!res.isJsonObject()) {
throw new JsonSyntaxException("Top level JSON object required");
}
return res.getAsJsonObject();
}
private static void assertThrows(Runnable r) {
try {
r.run();
fail();
} catch (JsonSyntaxException expected) {
// ok
}
}
@Test
public void testIt() {
assertThrows(() -> parse(""));
assertThrows(() -> parse("null"));
assertThrows(() -> parse("Abracadabra"));
assertThrows(() -> parse("[]"));
assertTrue(parse("{}").entrySet().isEmpty());
assertThrows(() -> parse("{a: }"));
assertThrows(() -> parse("{a: ,}"));
assertThrows(() -> parse("{a: 0,}"));
assertTrue(parse("{a: null}").get("a").isJsonNull());
assertEquals(0, parse("{a: 0}").get("a").getAsInt());
assertEquals("", parse("{a: ''}").get("a").getAsString());
assertEquals("", parse("{a: ""}").get("a").getAsString());
assertEquals(0, parse("{a: []}").get("a").getAsJsonArray().size());
//assertThrows(() -> parse("{a: [1,]}")); // TODO: this parses without error to {"a":[1,null]}
}
}
以上是关于如何使用GSON检查JSON在Java中是否有效?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用带有 Kotlin 的 Gson 库访问 JSON 有效负载中的嵌套值
如何检查传递的对象是否是MarkLogic中的有效JSON?