如何使用GSON检查JSON在Java中是否有效?

问题描述 投票:7回答:4

我有方法必须检查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

java json gson
4个回答
8
投票

虽然这对你来说可能很奇怪

"bncjbhjfjhj"

确实是有效的json,因为它是一个字符串,它是唯一的字符串。

根据不那么新的JSON RFC

JSON文本是序列化值。请注意,某些先前的JSON规范将JSON文本约束为对象或数组。只生成调用JSON文本的对象或数组的实现将是可互操作的,因为所有实现都将接受这些作为符合JSON文本。


5
投票

你不应该使用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));

输出:

真正 假


3
投票

根据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;
    }

现在随机看字符串bncjbhjfjhjfalse{"status": "UP"}是真的。


0
投票

另一种选择是将自定义的后检查应用到顶级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]}
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.