JSON เริ่มด้วย“ [” ได้ไหม?


178

จากสิ่งที่ฉันสามารถอ่านได้บนjson.orgสตริง JSON ทั้งหมดควรเริ่มต้นด้วย{(วงเล็บปีกกา) และ[ตัวอักษร (วงเล็บเหลี่ยม) แสดงองค์ประกอบอาร์เรย์ใน JSON

ฉันใช้json4jห้องสมุดและได้รับอินพุตที่เริ่มต้นด้วย[ดังนั้นฉันจึงไม่คิดว่านี่เป็น JSON ที่ถูกต้อง ผมมองช่วงสั้น ๆ ที่สคี JSON แต่ฉันไม่สามารถจริงๆพบว่ามันระบุว่าไฟล์ JSON ไม่สามารถเริ่มต้นด้วยหรือว่ามันจะสามารถเริ่มต้นด้วย[{


(เห็นได้ชัดว่ามีไลบรารี JSON ที่ออกแบบมาไม่ดีหลายตัวที่ต้องการให้คุณรู้ว่าเป็นประเภท JSON นอกสุด "แก้ไข" ที่ง่ายที่สุดที่นี่คือการล้อมรอบสตริง JSON ด้วย[]แยกวิเคราะห์เป็นอาร์เรย์และใช้องค์ประกอบอาร์เรย์แรก)
Hot Licks

เห็นได้ชัดว่าปลอดภัยกว่าที่จะเริ่มต้นด้วย {และไม่ใช่ [เพื่อไม่ให้เป็นอาร์เรย์ Javascript ที่ถูกต้องและไม่สามารถใช้สำหรับการโจมตี CSRF ได้
David Klempfner

คำตอบ:


218

JSON สามารถเป็นได้ทั้งอาร์เรย์หรือวัตถุ โดยเฉพาะจาก json.org:

JSON สร้างขึ้นด้วยสองโครงสร้าง:

  • ชุดของคู่ชื่อ / ค่า ในภาษาต่างๆสิ่งนี้จะถูกรับรู้ในฐานะวัตถุ, บันทึก, โครงสร้าง, พจนานุกรม, ตารางแฮช, รายการคีย์หรืออาร์เรย์ที่เชื่อมโยง
  • รายการสั่งซื้อของค่า ในภาษาส่วนใหญ่สิ่งนี้ถูกรับรู้เป็น
    อาร์เรย์เวกเตอร์รายการหรือลำดับ

จากนั้นจะอธิบายโครงสร้างทั้งสองดังนี้: วัตถุ JSON อาร์เรย์ JSON

โปรดทราบว่าอักขระเริ่มต้นและตัวลงท้ายเป็นวงเล็บปีกกาและวงเล็บเหลี่ยมตามลำดับ

แก้ไข
และจากที่นี่: http://www.ietf.org/rfc/rfc4627.txt

ข้อความ JSON เป็นลำดับของโทเค็น ชุดโทเค็นประกอบด้วยอักขระโครงสร้างหกตัว, ตัวเลข, และชื่อตัวอักษรสามชื่อ

ข้อความ JSON เป็นวัตถุหรืออาร์เรย์ที่ทำให้เป็นอนุกรม

อัปเดต (2014)

เมื่อวันที่มีนาคม 2014 มี 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 สามารถเริ่มต้นด้วยวงเล็บเหลี่ยม (เช่นอาร์เรย์) แต่นอกเหนือจากวัตถุและอาร์เรย์ก็สามารถตอนนี้ยังเป็นตัวเลข, สตริงหรือค่าfalse, หรือnulltrue

นอกจากนี้สิ่งนี้ได้เปลี่ยนไปจากการอ้างอิง RFC 4627 ก่อนหน้าของฉัน (เน้นการเน้น):

ข้อความ JSON เป็นลำดับของโทเค็น ชุดโทเค็นประกอบด้วยอักขระโครงสร้างหกตัว, ตัวเลข, และชื่อตัวอักษรสามชื่อ

ข้อความ JSON เป็นอันดับคุ้มค่า โปรดทราบว่าข้อกำหนดก่อนหน้านี้บางอย่างของ JSON จำกัด ข้อความ JSON ให้เป็นวัตถุหรืออาร์เรย์ การใช้งานที่สร้างเฉพาะวัตถุหรืออาร์เรย์ที่ข้อความ JSON ถูกเรียกใช้จะทำงานร่วมกันในแง่ที่ว่าการใช้งานทั้งหมดจะยอมรับสิ่งเหล่านี้ว่าสอดคล้องกับตำรา JSON


ขอบคุณฉันดูรูปนั้นหลายครั้งดูเหมือนว่ามีปัญหากับห้องสมุด json4j ซึ่งไม่ชอบ json กับ [
Tiberiu

1
@Tiberiu Hajas: ฉันต้องใช้เวลาซักหน่อยในการทำความเข้าใจเมื่อฉันพบมันครั้งแรก แต่หลังจากเห็นตัวอย่างของ JSON และเปรียบเทียบพวกเขาฉันชอบวิธีที่พวกเขาทำ เกี่ยวกับ json4j บางทีคุณสามารถส่งรายงานข้อผิดพลาดไปยังห้องสมุด json4j ของผู้สร้าง
Richard Marskell - Drackir

ฉันอาจมาสายสำหรับงานปาร์ตี้ แต่สิ่งที่ฉันพบใน RFC 8259 กล่าวว่าข้อความ JSON เป็นลำดับของโทเค็นที่เกิดขึ้นจากจุดโค้ด Unicode ที่สอดคล้องกับไวยากรณ์ค่า JSON ชุดโทเค็นรวมถึงโทเค็นโครงสร้างหก, สตริง, ตัวเลขและโทเค็นชื่อที่แท้จริงสามตัว ดูเหมือนว่านี่เป็นสิ่งที่ถูกต้อง: {"1234"}, {true} อย่างไรก็ตามสิ่งนี้แสดงถึงอะไร? นี่ไม่ใช่อาร์เรย์เพราะไม่มี <code> [] </code> ไม่ใช่ทั้งวัตถุนี้เพราะมีสองรายการ
Nicholas Humphrey

1
@NicholasHumphrey สิ่งที่ฉันเขียนด้านบนยังคงใช้ใน 8259 ในส่วนที่ 2 เดียวกัน (ไวยากรณ์ JSON) JSON- ข้อความ (aka เอกสาร JSON) ถูกกำหนดเป็น: JSON-text = ws value wsโดยที่ "ค่า JSON ต้องเป็นวัตถุอาร์เรย์ตัวเลขหรือสตริง หรือหนึ่งในสามชื่อตามตัวอักษรต่อไปนี้: false, null, true "ต่อส่วนที่ 3 (ค่า) ตัวอย่างของคุณไม่เป็นไปตามข้อ จำกัด เหล่านั้นดังนั้นจึงไม่ถูกต้อง JSON
Richard Marskell - Drackir

8

ถ้าสตริงที่คุณจะเริ่มต้นด้วยการแยกรั้งซ้าย ([) คุณสามารถใช้JSONArray.parseเพื่อให้ได้กลับวัตถุ JSONArray และจากนั้นคุณสามารถใช้get(i)ที่ฉันเป็นดัชนีจาก 0 ถึงกลับ size()-1JSONArray

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
โค้ดที่ง่ายขึ้นอาจใช้ instanceof ของ JSONArray กับ instanceof ของ JSONObject บนอ็อบเจกต์ที่ส่งคืนจาก get call เพื่อกำหนดคลาสที่ควรใช้ในการแยกวิเคราะห์ ...
Nathaniel Mills

5

JSON.ORG เว็บไซต์บอกว่า ....

https://www.json.org/

เว็บไซต์ระบุไว้อย่างชัดเจนดังต่อไปนี้:

JSON สร้างขึ้นด้วยสองโครงสร้าง:

  1. ชุดของคู่ชื่อ / ค่า ในภาษาต่างๆสิ่งนี้จะถูกรับรู้ในฐานะวัตถุ, บันทึก, โครงสร้าง, พจนานุกรม, ตารางแฮช, รายการคีย์หรืออาร์เรย์ที่เชื่อมโยง

  2. รายการสั่งซื้อของค่า ในภาษาส่วนใหญ่สิ่งนี้ถูกรับรู้เป็นอาร์เรย์เวกเตอร์รายการหรือลำดับ

เหล่านี้เป็นโครงสร้างข้อมูลสากล ภาษาการเขียนโปรแกรมที่ทันสมัยทั้งหมดสนับสนุนภาษาเหล่านี้ในรูปแบบเดียวหรืออีกรูปแบบหนึ่ง มันสมเหตุสมผลว่ารูปแบบข้อมูลที่สามารถใช้แทนกันได้กับภาษาการเขียนโปรแกรมยังขึ้นอยู่กับโครงสร้างเหล่านี้ ใน JSON พวกเขาใช้แบบฟอร์มเหล่านี้:

วัตถุ:

วัตถุคือชุดคู่ของชื่อ / ค่าที่ไม่เรียงลำดับ วัตถุเริ่มต้นด้วย {(วงเล็บปีกกาซ้าย) และลงท้ายด้วย} (วงเล็บปีกกาขวา) แต่ละชื่อจะตามด้วย: (โคลอน) และคู่ชื่อ / ค่าจะถูกคั่นด้วย, (คอมมา)

{string: value, string: value}

ARRAY:

อาร์เรย์คือชุดของค่าที่สั่ง อาร์เรย์เริ่มต้นด้วย [(วงเล็บเหลี่ยมซ้าย) และลงท้ายด้วย] (วงเล็บขวา) ค่าจะถูกคั่นด้วย, (จุลภาค)

[value, value, value ….]

VALUE:

ค่าสามารถเป็นสตริงในเครื่องหมายคำพูดคู่หรือตัวเลขหรือจริงหรือเท็จหรือเป็นโมฆะหรือวัตถุหรืออาร์เรย์ โครงสร้างเหล่านี้สามารถซ้อนกันได้

STRING:

สตริงคือลำดับของอักขระ Unicode ที่เป็นศูนย์หรือมากกว่าห่อด้วยเครื่องหมายคำพูดคู่โดยใช้เครื่องหมายแบ็กสแลช อักขระถูกแสดงเป็นสตริงอักขระเดียว สตริงเป็นอย่างมากเช่นสตริง C หรือ Java

จำนวน:

ตัวเลขนั้นคล้ายกับหมายเลข C หรือ Java มากยกเว้นว่าจะไม่มีการใช้รูปแบบฐานแปดและเลขฐานสิบหก

เกี่ยวกับ WHITESPACE:

ช่องว่างสามารถแทรกระหว่างโทเค็นคู่ใดก็ได้ ยกเว้นรายละเอียดการเข้ารหัสเล็กน้อยซึ่งอธิบายภาษาได้อย่างสมบูรณ์


ดีกับตัวอย่าง; มันช่วยให้ฉันเขียนหน่วยทดสอบ JSON validator ของฉันให้เสร็จ ฉันไม่แน่ใจว่าสตริงนั้นหมายถึงอะไร (เช่นต้องเป็นสตริงภายในเครื่องหมายคำพูดคู่)
gimlichael

ฉันเห็นว่ามันอาจจะสับสนประโยคนั้นอาจจะเริ่มกระชับขึ้นดังนี้: "ลำดับของอักขระ Unicode ที่เป็นศูนย์หรือมากกว่านั้น .... " ฉันเชื่อว่าผู้เขียนอาจเพิ่มมันเพื่อเน้น ฉันวางมันในแบบที่ทำให้ง่ายต่อการเห็นประเด็นสำคัญบางอย่าง แม้ว่าจะเป็นการตอบกลับล่าช้าฉันหวังว่าจะเพิ่มความชัดเจนหากจำเป็น
J. Moreno
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.