250

From what I can read on json.org, all JSON strings should start with { (curly brace), and [ characters (square brackets) represent an array element in JSON.

I use the json4j library, and I got an input that starts with [, so I didn't think this was valid JSON. I looked briefly at the JSON schema, but I couldn't really find it stated that a JSON file cannot start with [, or that it can only start with {.

Matt
  • 9,068
  • 12
  • 64
  • 84
Tiberiu
  • 2,870
  • 3
  • 20
  • 17
  • 1
    (There are apparently several ill-designed JSON libraries that require you to know the outer-most JSON type. The simplest "fix" here is to surround the JSON string with `[]`, parse it as an array, and take the first array element.) – Hot Licks Nov 10 '12 at 02:56
  • 2
    Apparently it's safer to have it start with { and not [ so that it isn't a valid Javascript array, and can't be used for CSRF attacks. – David Klempfner Sep 05 '18 at 01:18
  • 1
    We have some online validators(like https://jsonlint.com) in 2022. We can check its validation and get feedback about the problems. – cansu Mar 04 '22 at 07:23

4 Answers4

293

JSON can be either an array or an object. Specifically off of json.org:

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an
    array, vector, list, or sequence.

It then goes on to describe the two structures as: A JSON object A JSON array

Note that the starting and ending characters are curly brackets and square brackets respectively.

Edit
And from here: http://www.ietf.org/rfc/rfc4627.txt

A JSON text is a sequence of tokens. The set of tokens includes six structural characters, strings, numbers, and three literal names.

A JSON text is a serialized object or array.

Update (2014)

As of March 2014, there is a new JSON RFC (7159) that modifies the definition slightly (see pages 4/5).

The definition per RFC 4627 was: JSON-text = object / array

This has been changed in RFC 7159 to: JSON-text = ws value ws

Where ws represents whitespace and value is defined as follows:

A JSON value MUST be an object, array, number, or string, or one of the following three literal names:

false null true

So, the answer to the question is still yes, JSON text can start with a square bracket (i.e. an array). But in addition to objects and arrays, it can now also be a number, string or the values false, null or true.

Also, this has changed from my previous RFC 4627 quote (emphasis added):

A JSON text is a sequence of tokens. The set of tokens includes six structural characters, strings, numbers, and three literal names.

A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array. Implementations that generate only objects or arrays where a JSON text is called for will be interoperable in the sense that all implementations will accept these as conforming JSON texts.

  • thanks, I look at that figure many times, apparently there is a problem with json4j library, which doesn't like a json with [. – Tiberiu Feb 17 '11 at 21:28
  • 1
    @Tiberiu Hajas: It took me a little while to understand it when I first found it. But after seeing some examples of JSON and comparing them, I really like how they did it. Regarding json4j, perhaps you can submit a bug report to the json4j library's [creator](http://sourceforge.net/project/memberlist.php?group_id=224370). – Richard Marskell - Drackir Feb 17 '11 at 22:04
  • I'm probably late for the party. But what I found in RFC 8259 says that A JSON text is a sequence of tokens formed from Unicode code points that conforms to the JSON value grammar. The set of tokens includes six structural tokens, strings, numbers, and three literal name tokens. This sounds like something like this is legit: {"1234"},{true}. However what does this represent? This is not an array, because there is no [], neither is this an object, because there are two of them. – Nicholas Humphrey May 19 '18 at 20:42
  • 1
    @NicholasHumphrey What I wrote above still applies in 8259. In that same section 2 (JSON Grammar) JSON-text (aka a JSON document) is defined as: `JSON-text = ws value ws` where "A JSON value MUST be an object, array, number, or string, or one of the following three literal names: false, null, true" per Section 3 (Values). Your example doesn't satisfy those constraints and so is not valid JSON. – Richard Marskell - Drackir Feb 27 '19 at 17:35
  • @Richard Marskell - Drackir: I was trying to find a visual representation of the JSON file structure and all the rules. Your comment helped me find exactly what I needed. https://www.json.org/json-en.html Thanks a ton, man. Your comment got me to where I needed to go. :) – GroggyOtter Sep 11 '20 at 01:44
  • So to sum up the 2014 change, valid json used to be an object or array, but now it's an object, array, or a simple value? – jschmitter Oct 17 '21 at 20:49
12

If the string you are parsing begins with a left brace ([) you can use JSONArray.parse to get back a JSONArray object and then you can use get(i) where i is an index from 0 through the returned JSONArray's size()-1.

import java.io.IOException;
import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;

public class BookListTest {
   public static void main(String[] args) {
      String jsonBookList = "{\"book_list\":{\"book\":[{\"title\":\"title 1\"},{\"title\":\"title 2\"}]}}";
      Object book_list;
      try {
         book_list = JSONObject.parse(jsonBookList);
         System.out.println(book_list);
         Object bookList = JSONObject.parse(book_list.toString()).get("book_list");
         System.out.println(bookList);
         Object books = JSONObject.parse(bookList.toString()).get("book");
         System.out.println(books);
         JSONArray bookArray = JSONArray.parse(books.toString());
         for (Object book : bookArray) {
            System.out.println(book);
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Which produced output like:

{"book_list":{"book":[{"title":"title 1"},{"title":"title 2"}]}}
{"book":[{"title":"title 1"},{"title":"title 2"}]}
[{"title":"title 1"}, {"title":"title 2"}]
{"title":"title 1"}
{"title":"title 2"}

Note: if you attempted to call JSONObject.parse(books.toString()); you would get the error you encountered:

java.io.IOException: Expecting '{' on line 1, column 2 instead, obtained token: 'Token: ['
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
Nathaniel Mills
  • 321
  • 4
  • 7
  • 2
    More simple code might use instanceof JSONArray versus instanceof JSONObject on the object returned from the get call to determine which class should be used to parse the object... – Nathaniel Mills Jun 18 '12 at 18:55
11

JSON.ORG WEBSITE SAYS ....

https://www.json.org/

The site clearly states the following:

JSON is built on two structures:

  1. A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

  2. An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangeable with programming languages also be based on these structures. In JSON, they take on these forms:

OBJECT:

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

{string: value, string: value}

ARRAY:

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

[value, value, value ….]

VALUE:

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

STRING:

A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

NUMBER:

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

ABOUT WHITESPACE:

Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.

J. Moreno
  • 161
  • 1
  • 5
  • 1
    Good with the examples; it helped me finish writing my unit test for a JSON validator. I was not sure what was meant by string (eg. it must be a string inside double quotes). – gimlichael Mar 23 '19 at 16:05
  • I see how that could be confused, the sentence could have been a bit more concise starting as follows: " A sequence of zero or more Unicode characters ...." I believe the author may have added it for emphasis. I laid it out in a way that made it easier to see some of the key points. Although a late response, I hope that adds some clarity if needed. – J. Moreno Nov 19 '19 at 08:22
2

Short answer is YES

In a .json file you can put Numbers (even just 10), Strings (even just "hello"), Booleans (true, false), Null (even just null), arrays and objects. https://www.json.org/json-en.html

Using just Numbers, Strings, Booleans and Null are not logical because in .jon files we use more complicated structured data like arrays and object (mostly mix nested versions).

Below you can find a sample JSON data with array of object and start with "[" https://jsonplaceholder.typicode.com/posts

Arin Yazilim
  • 939
  • 8
  • 6