2017-04-05 91 views
4

我有方法必須檢查JSON是否有效,發現在How to check whether a given string is valid JSON in Java但它不起作用。如何使用GSON檢查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也。

+0

你找誰模式驗證? – efekctive

回答

1

我找到了解決辦法,但使用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的大小是多少? –

+0

不大。它用於從Springboot應用程序讀取健康檢查。 3或4級嵌套。 – QkiZ

+0

他們有一個特殊的JsonParser:http://www.javadoc.io/doc/com.google.code.gson/gson/2.8.2 – Andrew

6

雖然它可能是奇怪你

"bncjbhjfjhj" 

確實是有效的JSON,因爲它是一個字符串,它的唯一的字符串。

按照不那麼新JSON RFC

一個JSON文本是一個序列化值。請注意,JSON的某些以前的 規範將JSON文本約束爲一個對象或一個 數組。僅生成對象或數組(其中調用JSON文本的對象或數組)的實現將可互操作,因爲所有 實現都將接受這些爲符合JSON文本。

+0

儘管你是對的,OP實際上是問爲什麼'Gson'不會拒絕'bncjbhjfjhj'(沒有引號)作爲無效的JSON文檔。 –

+1

因爲它是有效的JSON?它只是一個普通的字符串 – WilomGfx

+2

OP正在使用'renderHtml.isJson(「bncjbhjfjhj」)'而不是'renderHtml.isJson(「\」bncjbhjfjhj \「」)'來測試它。 –

3

你不應該使用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
類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)); 

輸出:


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]} 
    } 

}