Как проверить, действительно ли JSON в Java с помощью GSON?
у меня есть метод, который должен проверить, действителен ли JSON, найденный на Как проверить, является ли данная строка допустимой JSON в 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
также.
4 ответов
в то время как это может быть странно для вас
"bncjbhjfjhj"
действительно является допустимым json, так как это строка, и ее единственная строка.
Согласно не столь новому JSON RFC
текст JSON является сериализованным значением. Обратите внимание, что некоторые предыдущие спецификации JSON ограничили текст JSON как объект или матрица. Реализации, генерировать только объекты или массивы, где Вызываемый текст JSON будет интерактивным в том смысле, что это все реализации будут принимать их как соответствующие тексты JSON.
вы не должны использовать Gson
чтобы сделать такую проверку:
-
Gson
- это объект, который выполняет десериализации поэтому он десериализует весь JSON как объект в памяти. -
Gson
, и я этого не знал, может быть, не очень строгий для некоторых инвалидов JSONs: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.гуглить.гсон.внутренний.LinkedTreeMap
класс java.ленг.Строка
то, что вы можете сделать здесь, это использовать 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));
выход:
true
ложные
я нашел решение, но с использованием org.json
библиотека, по данным Как проверить, является ли данная строка допустимой JSON в 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]}
}
}