Json簡介

轉(zhuǎn)載: http://www.reibang.com/p/8b428e1d1564#

JSON概覽

JSON(JavaScript Object Notation)是一種基于文本的數(shù)據(jù)交換格式菱涤。無論你的應(yīng)用是用哪種開發(fā)語言編寫的(Java/EE序调,Ruby帚称,PHP蔚晨,C#/.Net等等)敷搪,你都可以使用JSON來通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交互和處理。幾乎所有的編程語言都有很好的庫或第三方工具來提供基于JSON的API支持潜索,因此你可以非常方便地使用任何自己喜歡的編程語言來處理JSON數(shù)據(jù)抢野。而另一方面隨著REST、像MongoDB這樣的NoSQL技術(shù)或標(biāo)準(zhǔn)的廣泛使用策吠,JSON也正成為一種被推薦的數(shù)據(jù)交互格式逛裤。

JSON是在2001年,由Douglas Crockford創(chuàng)建的猴抹,并且被IETF(Internet Engineering Task Force)定義為RFC 4627標(biāo)準(zhǔn)带族,詳請(qǐng)參考:http://tools.ietf.org/html/rfc4627。JSON的媒體類型被定義為 application/json蟀给,而文件的后綴為.json蝙砌。

JSON是什么

JSON是一種簡單數(shù)據(jù)格式,它有三種數(shù)據(jù)結(jié)構(gòu):

  • 鍵值對(duì) —— Name/Value (Key/Value)
  • 對(duì)象 —— Object
  • 數(shù)組 —— Arrays

一個(gè)有效的JSON文檔需要被包含在一對(duì)花括號(hào)內(nèi)
{ JSON-Data }

請(qǐng)注意跋理,有些開發(fā)社區(qū)或線上文檔直接將上面的JSON文檔稱為JSON字符串择克,這兩者的意思是一樣的

為什么使用JSON

JSON被認(rèn)為是XML的很好替代者前普。因?yàn)镴SON的可讀性非常好肚邢,而且它沒有像XML那樣包含很多冗余的元素標(biāo)簽,這使得應(yīng)用在使用JSON進(jìn)行網(wǎng)絡(luò)傳輸以及進(jìn)行解析處理的速度更快拭卿,效率更高骡湖。

鍵值對(duì) —— Name/Value

鍵值對(duì)是JSON中最基本的數(shù)據(jù)結(jié)構(gòu):
{ “firstName”: “John”}

在上面的例子中屬性"firstName"是用一對(duì)雙引號(hào)括起來的一個(gè)字符串。而它的值"John"在這個(gè)例子中也是一個(gè)字符串峻厚,當(dāng)然它還可以是其他類型响蕴,具體可參考后面數(shù)據(jù)類型的章節(jié)。在市面上很多的產(chǎn)品或技術(shù)聲稱他們使用的是JSON數(shù)據(jù)格式惠桃,但他們?cè)诙x屬性時(shí)浦夷,并沒有用雙引號(hào)將屬性名稱括起來,其實(shí)這是違反JSON定義標(biāo)準(zhǔn)的刽射。

對(duì)象 —— Object

一個(gè)JSON對(duì)象是包含了一組未排序鍵值對(duì)的集合军拟。下面例子中的address就是一個(gè)JSON對(duì)象:

{
    “address” : {
        “l(fā)ine1” : “555 Main Street”,
        “city” : “Denver”,
        “stateOrProvince” : “CO”,
        “zipOrPostalCode” : “80202”,
        “country” : “USA”
    }
}

上面的例子中address對(duì)象包含了5個(gè)屬性,它們之間用,進(jìn)行分割誓禁。

數(shù)組 —— Array

JSON中[]來包含數(shù)組元素懈息,參考下面的例子:

{
    “people” : [
        { “firstName”: “John”, “l(fā)astName”: “Smith”, “age”: 35 },
        { “firstName”: “Jane”, “l(fā)astName”: “Smith”, “age”: 32 }
    ]
}

數(shù)據(jù)類型

JSON中的數(shù)值(鍵值對(duì)中的值)可以是以下任意一種:
Object
Array
String
Number
Boolean
null

Number

數(shù)值類型數(shù)據(jù)可以是整型也可以是雙精度的浮點(diǎn)型數(shù)據(jù)。下面是一些示例:
“age”: 29“cost”: 299.99“temperature”: -10.5“speed_of_light”: 1.23e11“speed_of_light”: 1.23e+11“speed_of_light”: 1.23E11“speed_of_light”: 1.23E+11

上面的屬性(如age等)都是用雙引號(hào)括起來的字符串摹恰,而數(shù)值是不需要用雙引號(hào)括起來的辫继。你可以在數(shù)值前加上-號(hào)來表示負(fù)數(shù)怒见,也可以采用科學(xué)計(jì)數(shù)法。但不能在數(shù)值前加0或使用16進(jìn)制來表示一個(gè)數(shù)值姑宽。

Boolean

JSON中的Boolean值可以用true或false來表示遣耍。不用加{}
{ “emailValidated” : true}
Boolean值也不需要使用雙引號(hào)來修飾。

null

嚴(yán)格來說null并不是一個(gè)數(shù)據(jù)類型炮车,但它非常重要舵变,它表示一個(gè)屬性或元素沒有值。因此請(qǐng)注意** ' ' 表示的是空字符串瘦穆,而null表示的才是空值纪隙。**
{ “age” : null}

代碼注釋

JSON不允許在JSON文檔或字符串中添加注釋。注釋功能最早在JSON中是存在的扛或,但開發(fā)者們錯(cuò)誤地使用了它來輔助JSON數(shù)據(jù)的解析绵咱,當(dāng)Douglas Crockford意識(shí)到這種不好的使用實(shí)踐后,便取消了注釋功能熙兔,以保證JSON在不同計(jì)算平臺(tái)間作為交互數(shù)據(jù)格式的特性悲伶。

樣式

你可能已經(jīng)注意到了在之前的例子中,所有的屬性名稱都使用了駝峰式的命名規(guī)則住涉。這并不是JSON的一個(gè)標(biāo)準(zhǔn)要求麸锉,但這能夠幫助提高JSON文檔的可讀性,因此作為一個(gè)事實(shí)標(biāo)準(zhǔn)在所有JSON應(yīng)用中被使用秆吵。

語法

Douglas Crockford 在他的JSON網(wǎng)站http://www.json.org/中淮椰,給出了所有JSON語法語義的說明。另外還有一個(gè)iOS App JSON Pro FREE可以用來通過示例學(xué)習(xí)或參考JSON纳寂。

JSON校驗(yàn)

一個(gè)文本文檔或字符串必須遵守JSON的語法定義主穗,才能被視作一個(gè)有效的JSON文檔。JSON文檔是否有效非常重要毙芜,因?yàn)樗苯記Q定了忽媒,你的JSON數(shù)據(jù)能否在不同的應(yīng)用中被正確地解析和使用。JSONLint提供了一個(gè)可交互的Web版JSON校驗(yàn)工具腋粥,你只需要將你的JSON文檔粘貼進(jìn)去晦雨,并點(diǎn)擊校驗(yàn)按鈕,它便會(huì)自動(dòng)進(jìn)行校驗(yàn)隘冲,并將問題顯示在下方闹瞧。

Paste_Image.png

在上面這個(gè)例子中展辞,這個(gè)JSON對(duì)象的city屬性沒有加上雙引號(hào)奥邮,導(dǎo)致校驗(yàn)失敗洽腺。在返回的提示中核无,顯示了“Expecting 'STRING', got 'undefined'”錯(cuò)誤。
JSONLint也提供了一個(gè)可以在Chrome中直接使用的插件已慢。

JSON數(shù)據(jù)模型

在應(yīng)用中手工編寫JSON文檔曲聂,會(huì)很枯燥并容易出錯(cuò)霹购。為了防止這樣的惡錯(cuò)誤 ,你可以使用JSONPad或JSON Editor Online這樣的工具朋腋,它們能夠幫助你構(gòu)建JSON邏輯模型(類似于UML),然后通過模型生成JSON文檔齐疙。

JSON Editor Online

[ JSON Editor Online] (http://jsoneditoronline.org/) 是一個(gè)在線JSON數(shù)據(jù)建模工具,他也提供了一個(gè)Chrome插件可以使用旭咽。

Paste_Image.png

瀏覽器中的JSON

Firefox和Chrome都提供了一些很好的插件方便開發(fā)人員查看或處理JSON數(shù)據(jù)贞奋。

REST Client

Rest Client是Firefox中的一個(gè)擴(kuò)展應(yīng)用。他能夠幫助開發(fā)人員在瀏覽器中調(diào)試REST風(fēng)格的Web Service穷绵。它最大的優(yōu)點(diǎn)是能將返回的JSON數(shù)據(jù)結(jié)果轿塔,以很好的格式顯示出來。

Paste_Image.png

JSONView

JSONView是一個(gè)FireFox和Chrome上的插件仲墨,能夠很好地將JSON數(shù)據(jù)打印出來勾缭,從而大大提高了JSON數(shù)據(jù)的可讀性。

Paste_Image.png

JSON與AJAX

AJAX可能是使用JSON數(shù)據(jù)中最常見的場(chǎng)景了目养。下面的這段代碼示例俩由,通過jQuery來調(diào)用一個(gè)REST風(fēng)格的Web Service,并處理返回的JSON對(duì)象癌蚁。

$.getJSON(‘http://example/service/addresses/home/1’,
    function(data) {
        var address = JSON.parse(data);
        console.log(“Address Line 1 = “ + address.line1);
    }
);

在上面的這段代碼中幻梯,$getJSON(這是一種jQuery中$.ajax()標(biāo)準(zhǔn)調(diào)用的一種縮寫形式)會(huì)發(fā)起一個(gè)HTTP GET 請(qǐng)求,調(diào)用Web Service努释,之后在它的隱式回調(diào)函數(shù)中碘梢,獲取返回的data數(shù)據(jù),并通過JSON.parse()方法將返回的數(shù)據(jù)轉(zhuǎn)換為JSON對(duì)象伐蒂。之后便可以像獲取普通屬性那樣(address.line1)獲取對(duì)象的屬性數(shù)值了煞躬。

JSON與JAVA

Jackson是JAVA中用來處理JSON的一個(gè)第三方庫。它很有名饿自,并且提供了一組非常好用的JSON API汰翠。下面就是它的一個(gè)例子:

import java.io.Writer;
import java.io.StringWriter;
import org.codehaus.jackson.map.ObjectMapper;

public class Address {
    private String line1;
    private String city;
    private String stateOrProvince;
    private String zipOrPostalCode;
    private String country;

    public Address() {}

    public String getLine1() {
        return line1;
    }

    public void setLine1(line1) {
        this.line1 = line1;
    }

    // Remaining getters and setters ...
}

Address addrOut = new Address();

// Call setters to populate addrOut …
ObjectMapper mapper = new ObjectMapper(); // Reuse this.
// Marshal Address object to JSON String.
Writer writer = new StringWriter();
mapper.writeValue(writer, addrOut);
System.out.println(writer.toString());

// Unmarshal Address object from JSON String.
String addrJsonStr =
“{“ +
    “\”address\” : {“ +
    “\”line1\” : \”555 Main Street\”,” +
    “\”city\” : \”Denver\”,”
    “\”stateOrProvince\” : \”CO\”,”
    “\”zipOrPostalCode\” : \”80202\”,” +
    “\”country\” : \”USA\”” +
    “}” +
“}”;

Address addrIn = mapper.readValue(addrJsonStr, Address.class);

除了Jackson之外龄坪,還有一些其他基于JAVA的第三方JSON API庫。
API
Source

Google GSON
http://code.google.com/p/google-json/

SOJO
http://sojo.sourceforge.net/

org.json (by DouglasCrockford)
http://www.json.org/java

json-lib
http://sourceforge.net/projects/json-lib/

json-io
http://code.google.com/p/json-io

jsontools
http://jsontools.berlios.de/

jsonbeans
http://code.google.com/p/jsonbeans/

JSON與RUBY

Ruby中也有很多與JSON相關(guān)的第三方庫复唤,而JSON gem是Ruby自帶的健田,下面就是它的用法:

require ‘json’
class Address
    attr_accessor :line1, :city, :state_or_province,
                  :zip_or_postal_code, :country

    def initialize(line1=’’, city=’’, state_or_province=’’,
        zip_or_postal_code=’’, country=’’)
        @line1 = line1
        @city = city
        @state_or_province = state_or_province
        @zip_or_postal_code = zip_or_postal_code
        @country = country
    end

    def to_json
        to_hash.to_json
    end

    def from_json!(str)
        JSON.parse(str).each { |var, val| send(“#{var}=”, val) }
    end

    private

    def to_hash
        Hash[instance_variables.map { |var| [var[1..-1].to_sym,
            send(var[1..-1])] }]
    end
end

JSON gem的to_json方法將字符串或哈希轉(zhuǎn)換為JSON。Address對(duì)象的to_json方法通過將它的成員轉(zhuǎn)換成哈希再對(duì)哈希值調(diào)用to_json佛纫,最終將一個(gè)Address對(duì)象轉(zhuǎn)換為JSON格式妓局。

addr1 = Address.new(‘555 Main Street’, ‘Denver’, ‘CO’, ‘80231’,
‘US’)
puts addr1.to_json
# Outputs the following …
{“l(fā)ine1”:”555 Main Street”,”city”:”Denver”,”state_or_
province”:”CO”,”zip_or_postal_code”:”80231”,”country”:”US”}

JSON gem的JSON.pase方法則將JSON字符串轉(zhuǎn)換為哈希。Address對(duì)象的from_jason!方法接收一個(gè)JSON字符串呈宇,然后調(diào)用JSON.parse來轉(zhuǎn)換哈希好爬,然后再在對(duì)象上分別設(shè)置這些哈希的值。
json_addr = <<END{ “l(fā)ine1” : “999 Broadway”, “city” : “Anytown”, “state_or_province” : “CA”, “zip_or_postal_code” : “90210”, “country” : “USA”}ENDaddr2 = Address.newaddr2.from_json!(json_addr)

除了JSON gem之外甥啄,還有以下一些Ruby的JSON第三方庫
API
Source

ActiveSupport JSON
http://api.rubyonrails.org/classes/ActiveSupport/JSON.html

Yajl
https://github.com/brianmario/yajl-ruby

Oj
https://github.com/ohler55/oj

JSON與RUBY ON RAILS
Ruby on Rails也提供了將Ruby對(duì)象轉(zhuǎn)換為JSON的功能存炮。下面的例子中的Controller使用了render方法將一個(gè)Ruby對(duì)象以JSON數(shù)據(jù)的格式進(jìn)行輸出。
Rails中的ApplicationController會(huì)負(fù)責(zé)對(duì)象與JSON數(shù)據(jù)之間的互相轉(zhuǎn)換 蜈漓。因此穆桂,不需要額外調(diào)用to_json方法。

JSON SCHEMA

JSON Schema用來定義JSON文檔的結(jié)構(gòu)融虽,它可以被用來驗(yàn)證和校驗(yàn)發(fā)送或收到的JSON文檔是否有效和規(guī)范享完。JSON Schema本身也是用JSON格式編寫的,它的具體定義可以參考http://json-schema.org有额。
下面是JSON Schema的部分結(jié)構(gòu)定義:
結(jié)構(gòu)
描述

type
對(duì)象的數(shù)據(jù)類型般又,如Object,array,string,number 等

$schema
提供Schema版本的URI

required
true/false

id
數(shù)據(jù)元素id

properties
數(shù)據(jù)元素的校驗(yàn)屬性,包括最大值巍佑,最小值茴迁,枚舉等

下面是JSON Schema的一個(gè)示例
“type”: “object”,“$schema”: “http://json-schema.org/draft-03/schema”,“id”: “#”,“required”: true,“properties”: { “registrants”: { “type”: “array”, “id”: “registrants”, “required”: true, “items”: { “type”: “object”, “required”: false, “properties”: { “address”: { “type”: “object”, “id”: “address”, “required”: true, “properties”: { “city”: { “type”: “string”, “id”: “city”, “required”: true }, “country”: { “type”: “string”, “id”: “country”, “required”: false }, “l(fā)ine1”: { “type”: “string”, “id”: “l(fā)ine1”, “required”: true }, “l(fā)ine2”: { “type”: “string”, “id”: “l(fā)ine2”, “required”: false }, “postalCode”: { “type”: “string”, “id”: “postalCode”, “required”: true }, “premise”: { “type”: “string”, “id”: “premise”, “required”: true, “enum”: [ “work”, “home”, “other” ] }, “stateOrProvince”: { “type”: “string”, “id”: “stateOrProvince”, “required”: true } } }, “firstName”: { “type”: “string”, “id”: “firstName”, “required”: true }, “l(fā)astName”: { “type”: “string”, “id”: “l(fā)astName”, “required”: true }, “phoneNumber”: { “type”: “object”, “id”: “phoneNumber”, “required”: true, “properties”: { “channel”: { “type”: “string”, “id”: “channel”, “required”: true, “enum”: [ “cell”, “work”, “home” ] }, “number”: { “type”: “string”, “id”: “number”, “required”: true } } } } } } } }

在上面的Schema中對(duì)JSON對(duì)象做了以下約束:
registrants必須是一個(gè)數(shù)組對(duì)象
phoneNumber的channel必須是cell, work, fax, home中的一個(gè)
address的premise必須是home, work, other中的一個(gè)。

一個(gè)使用上述JSON Schema的Web Service可以解析和處理下面這個(gè)JSON文檔:
{ "registrants": [ { "firstName": "Fred", "lastName": "Smith", "phoneNumber": { "channel": "cell", "number": "303-555-1212" }, "address": { "premise": "home", "line1": "555 Broadway NW", "line2": "# 000", "city": "Denver", "stateOrProvince": "CO", "postalCode": "88888", "country": "USA" } } ]}

JSON Schema 生成器
我們可以使用JSON Schema生成器來為一個(gè)有效的JSON文檔生成對(duì)應(yīng)的Schema句狼。你需要訪問(www.jsonschema.net)笋熬,然后按照以下步驟操作:
將你的JSON文檔粘貼到右側(cè)文本框
選擇JSON輸入選項(xiàng)
點(diǎn)擊Generate Schema按鈕

JSON Schema 校驗(yàn)器
我們可以用JSON Schema Validator來保證我們的JSON文檔時(shí)有效的。下面是針對(duì)不同開發(fā)語言的一些常見的JSON Schema 校驗(yàn)器腻菇。
校驗(yàn)器
編程語言
項(xiàng)目地址

JSV
JavaScript
https://github.com/garycourt/JSV

Ruby JSON Schema Validator
Ruby
https://github.com/hoxworth/jsonschema

json-schemavalidator
Java
https://github.com/fge/json-schema-validator

php-json-schema(by MIT)
PHP
https://github.com/hasbridge/php-json-schema

JSON.Net
.NET
http://james.newtonking.com/projects/json-net.aspx

除了上面這些與編程語言相關(guān)的校驗(yàn)器之外胳螟,你還可以直接使用在線的JSON Schema校驗(yàn)器( http://json-schema-validator.herokuapp.com ),將Schema和JSON文檔粘貼到左側(cè)的文本框中筹吐,然后點(diǎn)擊Validate按鈕糖耸,校驗(yàn)的結(jié)果就會(huì)顯示在屏幕右側(cè)。
總結(jié)
以上丘薛,我們已經(jīng)初步了解了JSON的核心定義和用法嘉竟,但對(duì)于JSON本身來說我們還只是了解了其中很小的一部分,還有許多與它相關(guān)的工具或技術(shù)可以使用。JSON作為一個(gè)數(shù)據(jù)標(biāo)準(zhǔn)舍扰,它已經(jīng)逐步替代XML成為Internet上最受歡迎的交互數(shù)據(jù)格式倦蚪。
簡書簽約作者:技匠,以上內(nèi)容歡迎大家分享到朋友圈/微博等边苹。如需轉(zhuǎn)載陵且,請(qǐng)通過簡信聯(lián)系授權(quán)。謝謝大家个束!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末慕购,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子茬底,更是在濱河造成了極大的恐慌沪悲,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阱表,死亡現(xiàn)場(chǎng)離奇詭異殿如,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)捶枢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門握截,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烂叔,你說我怎么就攤上這事」掏幔” “怎么了蒜鸡?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長牢裳。 經(jīng)常有香客問我逢防,道長,這世上最難降的妖魔是什么蒲讯? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任忘朝,我火速辦了婚禮,結(jié)果婚禮上判帮,老公的妹妹穿的比我還像新娘局嘁。我一直安慰自己,他們只是感情好晦墙,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布悦昵。 她就那樣靜靜地躺著,像睡著了一般晌畅。 火紅的嫁衣襯著肌膚如雪但指。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音棋凳,去河邊找鬼拦坠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛剩岳,可吹牛的內(nèi)容都是我干的贪婉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼卢肃,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼疲迂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起莫湘,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤尤蒿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后幅垮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腰池,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年忙芒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了示弓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呵萨,死狀恐怖奏属,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情潮峦,我是刑警寧澤囱皿,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站忱嘹,受9級(jí)特大地震影響嘱腥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拘悦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一齿兔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧础米,春花似錦分苇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掏颊,卻和暖如春糟红,著一層夾襖步出監(jiān)牢的瞬間艾帐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工盆偿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柒爸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓事扭,卻偏偏與公主長得像捎稚,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子求橄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容