JSON可以以“ [”开头吗?


184

根据我在json.org看到的内容,所有JSON字符串都应以{(大括号)开头,而[字符(方括号)表示JSON中的数组元素。

我使用的是json4j库,但输入的开头是[,所以我认为这不是有效的JSON。我简要地看了一下JSON模式,但是我找不到它表明JSON文件不能以开头[或只能以开头{


(显然,有几个设计不良的JSON库要求您了解最外面的JSON类型。这里最简单的“修复”是用包围JSON字符串[],将其解析为数组,并采用第一个array元素。)
热门点击2012年

显然,以{而不是[开头]是更安全的,因此它不是有效的Javascript数组,并且不能用于CSRF攻击。
David Klempfner

Answers:


228

JSON可以是数组或对象。特别是json.org:

JSON建立在两种结构上:

  • 名称/值对的集合。在各种语言中,这是作为对象,记录,结构,字典,哈希表,键列表或关联数组实现的。
  • 值的有序列表。在大多数语言中,这是通过
    数组,向量,列表或序列来实现的。

然后继续将这两种结构描述为: JSON对象 JSON数组

请注意,起始字符和结束字符分别是大括号和方括号。

编辑
并从这里开始:http : //www.ietf.org/rfc/rfc4627.txt

JSON文本是令牌序列。令牌集包括六个结构字符,字符串,数字和三个文字名称。

JSON文本是序列化的对象或数组。

更新(2014)

截至2014年3月,有一个新的JSON RFC(7159)对定义进行了轻微修改(请参阅第4/5页)。

RFC 4627的定义是: JSON-text = object / array

RFC 7159中将其更改为: JSON-text = ws value ws

其中ws表示空格,value并定义如下:

JSON值必须是对象,数组,数字或字符串,或者是以下三个文字名称之一:

false null true

因此,问题的答案仍然是肯定的,JSON文本可以以方括号(即数组)开头。但除了对象和数组,它现在也可以是数字,字符串或值falsenulltrue

此外,这与我以前的RFC 4627引用(添加了重点)有所不同:

JSON文本是令牌序列。令牌集包括六个结构字符,字符串,数字和三个文字名称。

JSON文本是序列化的。请注意,以前的某些JSON规范将JSON文本限制为对象或数组。从所有实现都将它们接受为符合JSON文本的意义上说,仅生成需要调用JSON文本的对象或数组的实现将可以互操作。


谢谢,我多次看过那个图,显然json4j库有问题,它不像[的json。

1
@Tiberiu Hajas:当我第一次发现它时,我花了一些时间来理解它。但是在查看了JSON的一些示例并进行了比较之后,我非常喜欢它们的实现方式。关于json4j,也许您可​​以将错误报告提交给json4j库的创建者
理查德·马斯克

我参加聚会可能迟到了。但是我在RFC 8259中发现,JSON文本是由符合JSON值语法的Unicode代码点形成的令牌序列。令牌集包括六个结构令牌,字符串,数字和三个文字名称令牌。这听起来像是合法的:{“ 1234”},{true}。但是,这代表什么呢?这不是数组,因为没有<code> [] </ code>,这也不是对象,因为有两个。
尼古拉斯·汉弗莱

1
@NicholasHumphrey我在上面写的内容仍然适用于8259。在第2节(JSON语法)中,JSON文本(又称JSON文档)定义为:JSON-text = ws value ws其中“ JSON值必须是对象,数组,数字或字符串,或以下三个文字名称之一:“第3节(值)为false,null,true”。您的示例不满足这些约束,因此不是有效的JSON。
理查德·马斯克

@Richard Marskell-Drackir:我正在尝试寻找JSON文件结构和所有规则的直观表示。您的评论帮助我找到了我所需要的。json.org/json-en.html 谢谢,伙计。您的评论使我到达了需要去的地方。:)
GroggyOtter

9

如果您要分析的字符串以左括号([)开头,则可以使用它JSONArray.parse来获取JSONArray对象,然后可以使用get(i)其中i是从0到返回的JSONArray的索引的地方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();
      }
   }
}

产生的输出如下:

{"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"}

注意:如果您尝试致电JSONObject.parse(books.toString());,则会收到遇到的错误:

java.io.IOException: Expecting '{' on line 1, column 2 instead, obtained token: 'Token: ['

1
从get调用返回的对象上,更简单的代码可能使用instanceof JSONArray与instanceof JSONObject来确定应使用哪个类来解析该对象...
Nathaniel Mills 2012年

6

JSON.ORG网站说..

https://www.json.org/

该网站明确声明以下内容:

JSON建立在两种结构上:

  1. 名称/值对的集合。在各种语言中,这是作为对象,记录,结构,字典,哈希表,键列表或关联数组实现的。

  2. 值的有序列表。在大多数语言中,这是通过数组,向量,列表或序列来实现的。

这些是通用数据结构。几乎所有现代编程语言都以一种或另一种形式支持它们。可以与编程语言互换的数据格式也应基于这些结构,这是有道理的。在JSON中,它们采用以下形式:

目的:

对象是名称/值对的无序集合。对象以{(左括号)开始,以}(右括号)结束。每个名称后跟有:(冒号),名称/值对之间以,(逗号)分隔。

{string: value, string: value}

阵列:

数组是值的有序集合。数组以[(左括号)开头,以](右括号)结尾。值之间以,(逗号)分隔。

[value, value, value ….]

值:

值可以是带双引号的字符串,也可以是数字,也可以是true或false或null,或者是对象或数组。这些结构可以嵌套。

串:

字符串是零个或多个Unicode字符的序列,使用反斜杠转义符将其括在双引号中。字符表示为单个字符串。字符串非常类似于C或Java字符串。

数:

除了不使用八进制和十六进制格式外,数字与C或Java数字非常相似。

关于白空间:

可以在任何一对标记之间插入空格。除了一些编码细节外,它完全描述了该语言。


很好的例子;它帮助我完成了为JSON验证程序编写单元测试的过程。我不确定字符串的含义(例如,它必须是双引号内的字符串)。
gimlichael

我知道如何将其混淆,该句子从以下开始可能更简洁:“一个零个或多个Unicode字符序列。我以一种易于理解某些关键点的方式进行了布局。尽管反应较晚,但我希望在需要时可以增加一些清晰度。
J. Moreno
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.