JSON'da null değerini temsil etme


422

JSON'da null değerleri döndürmek için tercih edilen yöntem nedir? İlkel için farklı bir tercih var mı?

Örneğin, sunucudaki nesnemin değeri olmayan "myCount" adlı bir Tamsayı varsa, bu değer için en doğru JSON şöyle olur:

{}

veya

{
    "myCount": null
}

veya

{
    "myCount": 0
}

Dizeler için aynı soru - eğer sunucuda "myString" null dizesi varsa, en iyi JSON:

{}

veya

{
    "myString": null
}

veya

{
    "myString": ""
}

ya da (Lord bana yardım et)

{
    "myString": "null"
}

Koleksiyonların JSON'da boş bir koleksiyon olarak temsil edilmesini seviyorum. Http://jtechies.blogspot.nl/2012/07/item-43-return-empty-arrays-or.html

Boş bir Dizi temsil edilir:

{
    "myArray": []
}

EDIT Özeti

'Kişisel tercih' argümanı gerçekçi görünmektedir, ancak kısa bir bakış açısıyla, bir topluluk olarak çok daha fazla sayıda farklı hizmet / kaynak tüketeceğiz. JSON yapısı için sözleşmeler, söz konusu hizmetlerin tüketimini ve yeniden kullanımını normalleştirmeye yardımcı olacaktır. Standart oluşturmaya gelince, Jackson sözleşmelerinin çoğunu birkaç istisna dışında kabul etmenizi öneririm:

  • Nesneler ilkellere göre tercih edilir.
  • Boş koleksiyonlar null yerine tercih edilir.
  • Değeri olmayan nesneler null olarak temsil edilir.
  • İlkeller değerlerini döndürür.

Çoğunlukla null değerlere sahip bir JSON nesnesi döndürüyorsanız, birden çok hizmete yeniden düzenleme için bir adayınız olabilir.

{

    "value1": null,

    "value2": null,

    "text1": null,

    "text2": "hello",

    "intValue": 0, //use primitive only if you are absolutely sure the answer is 0

    "myList": [],

    "myEmptyList": null, //NOT BEST PRACTICE - return [] instead

    "boolean1": null, //use primitive only if you are absolutely sure the answer is true/false

    "littleboolean": false

}

Yukarıdaki JSON, aşağıdaki Java sınıfından oluşturuldu.

package jackson;

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonApp {

    public static class Data {

        public Integer value1;

        public Integer value2;

        public String text1;

        public String text2 = "hello";

        public int intValue;

        public List<Object> myList = new ArrayList<Object>();

        public List<Object> myEmptyList;

        public Boolean boolean1;

        public boolean littleboolean;

    }

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(new Data()));
    }
}

Maven bağımlılığı:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.3.0</version>
</dependency>

5
En iyi yolu yok. Somut kullanım durumunuzda müşteri için tüketilmesi en kolay olanı seçin. Bunun yerine boş koleksiyonları döndürme ruhu içinde null, müşterinizin boş dizeyle daha iyi olup olmadığını düşünün ya da null- "null" kelimesini içeren bir dize geçerli bir değerden ayırt edilemez, bunu yapmayın.
Philipp Reichart

3
0 veya boş bir dize, null değerinden çok farklı anlamlara sahip olabilir; bu, mevcut olmayan öznitelikten farklı bir anlama sahip olabilir. Null değerini temsil etmek istiyorsanız null kullanın. En açık olanı.
John Sheehan

Objective-C'de NSNulltekli bir örneği olan tanımlı bir sınıf vardır. Bu örneğe yapılan başvuru JSON'lara eşdeğerdir null. Başka bir dilin de aynı şeyi yapabileceğini tahmin ediyorum. Tabii ki, varsayılan sınıfa dökülmeden önce alınan nesnenin sınıfını kontrol etmek gerekir - "null farkında" olduğu gibi.
Hot Licks

2
"Boş" bir listeye sahip olmanın Java için de en iyi yöntem olmadığını unutmayın: listenin boş olması bekleniyorsa listeyi boş bir listeye başlatın. O gerekiyorsa kalması buna initialise için (bir yeni liste ile toptan değiştirilmesi yerine değerler eklemek için değiştirilebilir çünkü örneğin) boş boş listesinde (yani ). Aksi takdirde ağrı olabilecek boş referans hataları önler. Collections.emptyList()
Periata Breatta

@HotLicks - bu yalnızca Objective-C dinamik olarak yazıldığından mümkündür. Örneğin Java'da (yararlı) bir Nullsınıfınız olamazdı çünkü değerlerini yalnızca kendi türündeki veya türündeki nesnelere atayabiliyordunuz Object.
Periata Breatta

Yanıtlar:


378

Her birinin ayrıştırılmasını değerlendirelim:

http://jsfiddle.net/brandonscript/Y2dGv/

var json1 = '{}';
var json2 = '{"myCount": null}';
var json3 = '{"myCount": 0}';
var json4 = '{"myString": ""}';
var json5 = '{"myString": "null"}';
var json6 = '{"myArray": []}';

console.log(JSON.parse(json1)); // {}
console.log(JSON.parse(json2)); // {myCount: null}
console.log(JSON.parse(json3)); // {myCount: 0}
console.log(JSON.parse(json4)); // {myString: ""}
console.log(JSON.parse(json5)); // {myString: "null"}
console.log(JSON.parse(json6)); // {myArray: []}

Tl; dr burada:

Json2 değişkenindeki parça , JSON spesifikasyonunun gösterilme biçimidir null. Ancak her zaman olduğu gibi, ne yaptığınıza bağlıdır - bazen bunu yapmanın “doğru” yolu her zaman durumunuz için işe yaramaz. Kararınızı kullanın ve bilinçli bir karar verin.


JSON1 {}

Bu, boş bir nesne döndürür. Orada veri yok ve sadece aradığınız herhangi bir anahtarın ( myCountya da başka bir şey olsun) tip olduğunu söyleyecektir undefined.


JSON2 {"myCount": null}

Bu durumda, myCountdeğeri de olsa aslında tanımlanır null. Bu değil "ikisini birden aynı undefineddeğil null" ve tek bir koşul veya diğeri için test olsaydı JSON1 başarısız olur, oysa bu başarılı olabilir.

Bu temsil etmek kesin yoldur nullbaşına JSON spec .


JSON3 {"myCount": 0}

Bu durumda, myCount 0'dır. Bu, ile aynı nulldeğildir ve ile aynı değildir false. Koşullu ifadeniz değerlendirilirse myCount > 0, bunun olması faydalı olabilir. Ayrıca, buradaki değere dayalı hesaplamalar yapıyorsanız, 0 yararlı olabilir. nullAncak test etmeye çalışıyorsanız , bu aslında işe yaramayacaktır.


JSON4 {"myString": ""}

Bu durumda, boş bir dize alırsınız. Yine, JSON2'de olduğu gibi, tanımlanmıştır, ancak boştur. Sen girebilmek için test if (obj.myString == "")ancak test edemedi nullya undefined.


JSON5 {"myString": "null"}

Dize değerini null olarak ayarladığınızdan, bu muhtemelen size sorun çıkartacaktır; obj.myString == "null"ancak bu durumda değildir == null .


JSON6 {"myArray": []}

Bu size dizinizin myArrayvar olduğunu söyleyecektir , ancak boştur. Üzerinde bir sayım veya değerlendirme yapmaya çalışıyorsanız faydalıdır myArray. Örneğin, bir kullanıcının yayınladığı fotoğraf sayısını değerlendirmek istediğinizi varsayalım - yapabilirdiniz myArray.lengthve geri dönecekti 0: tanımlı, ancak yayınlanan fotoğraf yok.


1
Çok teşekkürler, çok yararlı. Sadece küçük bir yan düğüm; Play Json (scala) serileştirdiğinde Option [String] = Yok sonuç JSON1ie{}
Neil

207

nullsıfır değildir. Kendi başına bir değer değildir : değişkenin etki alanı dışındaki eksik veya bilinmeyen verileri gösteren bir değerdir.

nullJSON'da temsil etmenin tek bir yolu var . Şartnamelere göre ( RFC 4627 ve json.org ):

2.1. Değerler

JSON değeri bir nesne, dizi, sayı veya dize veya
aşağıdaki üç değişmez ad:

  yanlış null doğru

resim açıklamasını buraya girin


8
Null'un mevcut olması çok utanç verici. Boşuna 4 karakter. Değeri tamamen dışlamak güzel olurdu. json = '{"myValue":}';
Richard A Quadling

119
@Richard A Quadling - Hal Abelson'ın "İnsanların okuması için programlar yazılmalıdır ve sadece makinelerin çalışması için bu arada yazılmalıdır". 'Yanlış' kelimesini tercih ediyorum, sadece yanlışlıkla ihmal sorunu değil, programcının niyetini de doğrularım.
Scott Smith

13
@Dave Mayıs: "JSON değerleri program değildir" - Amacım açık bir şekilde niyeti işaret etmektir. Evet, ekstra dört karaktere mal oluyor ve bazı uygulamalar için fark önemli olabilir. Birçok olsa durumlarda, yapım faydaları ise hatalar yanlış görünüyorsa kadar küçük optimizasyonlar yararlarını ağır basar.
Scott Smith

11
@Dave Ayrıca, json.org'a göre JSON "insanların okuması ve yazması kolaydır."
Sophivorus

14
Ayrıca 4 ASCII karakteriyle ilgili sorun yaşarsanız, JSON en iyi yaklaşım değildir, İkili JSON'a veya daha iyisine saf bir ikili biçime bakın.
PhoneixS

26

Temsil etmenin sadece bir yolu vardır null; ile null.

console.log(null === null);   // true
console.log(null === true);   // false
console.log(null === false);  // false
console.log(null === 'null'); // false
console.log(null === "null"); // false
console.log(null === "");     // false
console.log(null === []);     // false
console.log(null === 0);      // false

Demek ki; JSON temsilcinizi tüketen istemcilerden herhangi biri ===işleci kullanıyorsa; onlar için bir sorun olabilir.

değersiz

Özelliğinin myCountdeğeri olmayan bir nesneniz olduğunu söylemek istiyorsanız :

{ "myCount": null }

özellik yok / eksik özellik

Öznitelikleri olmayan bir nesneye sahip olduğunuzu iletmek isterseniz:

{}

İstemci kodu erişmeye myCountve almaya çalışacaktır undefined; orada değil.

boş koleksiyon

myCountBoş bir liste niteliği olan bir nesneniz olduğunu iletmek isterseniz :

{ "myCount": [] }

Karşılaştırmalarla +1 iyi örnekler, ancak javascript ve json arasında ayrım yapmak yararlı olacaktır, yani javascript'te null ifadesinin json'la eşleşmesi gerekmiyordu (olmasına rağmen).
Mladen B.

15

Bu nullanahtar için bir değer olmadığını göstermek için kullanırdım. Örneğin, null"evinizdeki internete bağlanan cihaz sayısının" bilinmediğini göstermek için kullanın.

Diğer yandan, {}söz konusu anahtar geçerli değilse kullanın . Örneğin, nullherhangi bir aracı olmayan birine "aktif internet bağlantısı olan araç sayısı" sorusu sorulsa bile bir sayı göstermemelisiniz .

Bu varsayılan mantıklı olmadığı sürece herhangi bir değeri varsayılan önlemek. nullHiçbir değeri temsil etmek için kullanmaya karar verebilirsiniz, ancak kesinlikle "null"bunu yapmak için kullanmayın .


7

Değişken veri türü ( nulldizeler / nesneler, 0sayılar için) için "varsayılan" seçerim , ama gerçekten nesnenin ne olacağını tüketecek kodu kontrol edin. Unutmayın, bazen null/ default ve "not available" arasında bir ayrım vardır .

Check out boş nesne modeli - bazen yerine bazı özel nesne geçmek daha iyidir null(yani []dizinin yerine nulldiziler için veya ""dizeleri).


2

Bu kişisel ve durumsal bir seçimdir. Hatırlanması gereken önemli şey, boş dizenin ve sıfır sayısının kavramsal olarak farklı olmasıdır null.

Bir durumunda countmuhtemelen her zaman geçerli bir sayı istersiniz ( countbilinmeyen veya tanımlanmadığı sürece ), ancak dizelerde, kim bilir? Boş dize , uygulamanızda bir şey ifade edebilir. Ya da belki de değildir. Karar vermek size kalmış.


1

Göre JSON spec , dış kap üzerinde yorum çoğu ima edildiği gibi, bir sözlük (veya nesne ') olmak zorunda değildir. Ayrıca bir liste veya çıplak bir değer de olabilir (ör. Dize, sayı, boole veya null). JSON'da null bir değeri temsil etmek istiyorsanız, tüm JSON dizesi (JSON dizesini içeren tırnak işaretleri hariç) basittir null. Parantez yok, parantez yok, tırnak yok. Null değerine ( {"key1":null}) sahip bir anahtar veya null değerine ( [null]) sahip bir liste içeren bir sözlük belirtebilirsiniz , ancak bunlar null değerlerin kendileri değildir; bunlar uygun sözlükler ve listelerdir. Benzer şekilde, boş bir sözlük ( {}) veya boş bir liste ( []) de gayet iyi ancak boş da değil.

Python'da:

>>> print json.loads('{"key1":null}')
{u'key1': None}
>>> print json.loads('[null]')
[None]
>>> print json.loads('[]')
[]
>>> print json.loads('{}')
{}
>>> print json.loads('null')
None

Bağlı JSON teknik özellikler sayfasının sağ kenar çubuğundaki McKeeman Form gramerinin, çıplak nullgeçerli JSON'u oluşturduğuna dair iddiayı doğruladığını unutmayın . Ana gövde metni ve resimler belirsizdir ve eğer herhangi bir şey düşündürüyorsa, sadece nesneler ve diziler kökte geçerlidir.
yoyoyoyosef
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.