Java API for JSON Processing (JSON-P) standardı JSR-353 belirtiminde Java EE 7 şemsiyesi altında bulunan bir kurumsal java teknolojisidir. JSON-P ile JSON nesne ve dizilerini oluşturmak, oluşturulan JSON verilerini bir I/O ortamına okumak ve yazma işlemleri kolay bir biçimde gerçekleştirilebilmektedir. Bu yapılabilirliklerin konu alındığı yazıları okumak için devam eder bağlantıları izleyebilirsiniz (JSON-P-1 ve JSON-P-2).
Bu yazıda ise sizlerle JSON-P ile Stream bazlı JSON-P nesnelerinin nasıl üretilebileceğinden ve Stream bazlı veri sunabilen kaynaklardan, kısım kısım nasıl veri elde edilebileceğinden bahsetmek istiyorum. XML teknolojilerinde DOM ve SAX kütüphanelerini kullananlar, JSON-P içinde benzer yaklaşımların sunulup sunulmadığını merak edebilirler. Kısaca DOM ve SAX farkını özetleyecek olursak;
DOM
Java taraflı bir XML DOM ağacı oluşturulur ve tüm XML elamanları bir bütün olarak bellek alanında yer işgal ederler. DOM kullanımı SAX’a göre geliştirimi kolay iken, büyük XML veri yığınlarında bellek alanını tehdit eden sonuçlar doğurabilmektedir. JSON-P-1 ve JSON-P-2 uygulamalarında yer alan örnekler ve sınıflar, DOM kullanım yöntemine göre nesneleri bir bütün olarak kullanmaktadır.
SAX
Örneğin bir sunucu üzerinde çok uzun boyutlu bir XML kaynağı var, ve siz bu kaynak içerisindeki verilere bir bütün olarak değil de, belirli bir kısmına ihtiyaç duyuyorsunuz. Bu büyük boyutlu XML kaynağını tamamen uygulama içerisine çekmek mi istersiniz? Yoksa parça parça (stream) olarak mı elde etmek istersiniz? İşte SAX burada stream bazlı olarak verileri kısım kısım elde etmeyi sağlarken, bellek kullanımını verimli kılmaktadır. Fakat SAX ile veri elde ederken veya yazarken, DOM tekniğine göre geliştiriciye biraz daha fazla iş yükü bekler. Bu yazıda sunacağımız örnekler ve sınıflar ise, JSON-P’ nin sunduğu SAX (Simple API for XML) benzeri yaklaşımı açıklamaktadır.
Json-P standardında Stream bazlı operasyonlar için JsonGenerator ve JsonParser türünden nesneler kullanılmaktadır. JsonGenerator stream bazlı Json nesneleri oluşturmayı sağlarken, JsonParser ise verileri bir kaynaktan stream bazlı olarak kısım kısım okumaktadır.
JsonGenerator
JsonGenerator türünden nesneler Json#createGenerator metodu üzerinden oluşturulmaktadırlar. createGenerator(..) metodu Writer ve OutputStream ailelerinden sistem kaynaklarını metod parametresi olarak kabul etmektedir. Örneğin aşağıdaki örnekte üretilen JsonGenerator nesnesi, kendisi üzerinde yapılan işlemleri bir StringWriter üzerine aktarmaktadır.

try (JsonGenerator jsonUretec = Json
		.createGenerator(stringWriter = new StringWriter())) {

	jsonUretec.writeStartObject()
			.write("ad", "Mahsun Doğan")
			.write("yas", 25)
			.writeEnd();
}

System.out.println(stringWriter.toString());
Bu kod parçasının çalıştırılmasının ardından aşağıdaki Json çıktısı elde edilir.
{"ad":"Mahsun Doğan","yas":25}
JsonGenerator nesneleri, StringWriter nesnesine veri yazdırdığı gibi FileWriter nesneleri üzerinden dosya sistemine de stream bazlı olarak kayıt yapabilir. Bunun için tek yapılması gereken bir File nesnesi ile birlikte bir FileWriter nesnesi oluşturmaktır.
File jsonFile=new File("./src/main/resources/file.json");
if (!jsonFile.exists()) {
	jsonFile.createNewFile();
}

try (JsonGenerator jsonUretec2 = Json
		.createGenerator(fileWriter = new FileWriter(jsonFile))) {
	jsonUretec2.writeStartObject()
		.write("ad", "Selçuk Bahadır")
		.write("yas", 24)
		.writeStartObject("adres")
		.write("ulke", "Türkiye")
		.write("il", "Hakkari")
		.writeEnd()
		.writeStartArray("hobiler")
		.write("Yüzme").write("Atış").write("Futbol")
		.writeEnd()
		.writeEnd();
}
Buradaki JsonGenerator ile üretilen Json çıktısı ise, file.json dosyasına bakılarak görülür.

{
    "ad":"Selçuk Bahadır",
    "yas":24,
    "adres":{
        "ulke":"Türkiye",
        "il":"Hakkari"
    },
    "hobiler":[
        "Yüzme",
        "Atış",
        "Futbol"
    ]
}
JsonParser
JsonParser Reader veya InputStream türlerinden bir kaynaktan verileri stream bazlı olarak okumaya ve çözümlemeye yaramaktadır. Örneğin http://maps.googleapis.com/maps/api/geocode/json?address=Marmara+University&sensor=false adresinden dönen Json nesnesi JsonParser ile çözümlenebilir ve elde edilen veriler ihtiyaca göre kullanılabilir. Stream bazlı yazma ve okuma işlemlerinin en önemli özelliği, işiniz bittiğinde veri/depo kaynağıyla iletişimi koparabilme yeteneğidir. Örneğin Json nesnesinin 10. satırındaki bir alanın değerine ihtiyacınız var ve 10. satırdan sonra var olan 100 satır bilgiyi okumak istemiyorsunuz. Bunun için JsonParser#close metodunu çağırarak aktif akışı durdurabilirsiniz. Bu sayede ihtiyaç duymadığınız verilerle sistemi meşgul etmek durumunda kalmamış oluruz.

JsonParser jsonParser = Json.createParser(new URL("http://maps.googleapis.com/maps/api/geocode/json?address=Marmara+University&sensor=false").openStream());

MultiMap multiMap = MultiValueMap.decorate(new HashMap());
while (jsonParser.hasNext()) {

JsonParser.Event next = jsonParser.next();
switch (next) {
	case START_ARRAY:
	case START_OBJECT:
	case END_OBJECT:
	case END_ARRAY:
		break;
	case KEY_NAME:
		key = jsonParser.getString();
		break;
	case VALUE_STRING:
	case VALUE_NUMBER:
	case VALUE_TRUE:
	case VALUE_FALSE:
	case VALUE_NULL:
		value = jsonParser.getString();
		multiMap.put(key, value);
		break;

}

}

System.out.println(multiMap);
JsonParser ile bir JSON verisi parse edilirken, her bir olay bildirimi JsonParser.Event ile elde edilir. Örneğin kaynakta “{“ ifadesiyle karşılaşılırsa, event tipi START_OBJECT, “}” ile karşılaşılırsa olay tipi END_OBJECT olmaktadır. Keza bir Json anahtarıyla karşılaşılırsa KEY_NAME, bu anahtara karşılık gelen değeri ise türüne göre VALUE_STRING, VALUE_NUMBER, VALUE_TRUE, VALUE_FALSE veya VALUE_NULL olarak elde edebilmekteyiz. Bu örnekte tüm anahtar -> değer çiftleri elde edilmekte ve bir MultiMap veri yapısına eklenerek çıktılanmaktadır. Uygulama çalıştırıldığında oluşan çıktı aşağıdaki gibidir.

{location_type=[APPROXIMATE], long_name=[Marmara University, Eğitim Mh., Kadıköy, Istanbul, Istanbul, Turkey, 34722], status=[OK], formatted_address=[Marmara University, Eğitim Mh., 34722 Kadıköy/Istanbul Province, Turkey], lng=[29.0552020, 29.0488970, 29.05504490, 29.0552020, 29.0488970], types=[establishment, neighborhood, political, sublocality, political, locality, political, administrative_area_level_1, political, country, political, postal_code, university, establishment], short_name=[Marmara University, Eğitim Mh., Kadıköy, Istanbul, Istanbul, TR, 34722], lat=[40.9898720, 40.9848090, 40.989210, 40.9898720, 40.9848090]}
Örnek uygulamalara https://github.com/rahmanusta/JSON-P/ adresinden erişebilirsiniz.
Tekrar görüşmek dileğiyle.
Tag:backend, json, json-p, Stream
Share:
Rahman Usta	
Kodedu.com bünyesinde eğitim ve danışmanlık faaliyetleri sürdüren Rahman Usta, 2012 yılında yayına çıkan popülerJava Mimarisiyle Kurumsal Çözümler ve 2014 yılında yayınlanan Java 8 Ebook kitaplarının yazarıdır. Açık kaynak dünyasına katkı veren yazar, geliştirdiği AsciidocFX projesiyle Duke's Choice Award 2015 ödülünü kazanmıştır. Rahman ayrıca, Istanbul JUG'un ve Java standartlarını geliştiren JCP (Java Community Process)'in bir üyesidir. 2018 yılında Java Şampiyonu olarak seçilmiştir.
Previous post
Integration of Spring MVC and Mustache
6 Ağustos 2013	
Next post
Combine JaxRS 2.0 Rest Client, Java FX 2, Spring MVC and Hibernate
15 Ağustos 2013	
You may also like
Swagger Nedir? Neden kullanılır?
10 Ekim, 2018	
Spring CLI ile Spring Boot Projeleri Hazırlamak
21 Ağustos, 2017	
Spring Cloud Netflix ve Eureka Service Discovery
3 Temmuz, 2017	
Leave A Reply Cevabı iptal et
E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir
Δ
Arama:
E-posta listesine kayıt olun!
Ad-soyad
E-posta
HP
Abone ol
Gözde yazılar
JPA 2.1 Type Converter
19Nis2014
Distributed Map-Reduce Model using Java 8 and Java EE 7 WebSocket
16Kas2014
Online React.js Eğitimi ardından (15-25 Mayıs 2017)
31May2017
Jax-RS 2 and LongPolling based Chat Application
25Haz2013
Son Yazılar
Java’da Record’lar 27 Ocak 2020
Swagger Nedir? Neden kullanılır? 10 Ekim 2018
Spring CLI ile Spring Boot Projeleri Hazırlamak 21 Ağustos 2017
Spring Cloud Netflix ve Eureka Service Discovery 3 Temmuz 2017
Online React.js Eğitimi ardından (15-25 Mayıs 2017) 31 Mayıs 2017
Son Yorumlar
JWT (JSON Web Tokens) Nedir? Ne işe yarar? için Furkan
YAML Nedir? Neden YAML Kullanmalıyız? için shahriyar
Java Persistence API Nedir? (Giriş) için Utku
Java 8 – CompletableFuture ile Asenkron Programlama için Rahman Usta
Java 8 – CompletableFuture ile Asenkron Programlama için burak
Arşivler
Arşivler Ay seçin Ocak 2020 (1) Ekim 2018 (1) Ağustos 2017 (1) Temmuz 2017 (1) Mayıs 2017 (5) Nisan 2017 (1) Mart 2017 (1) Şubat 2017 (1) Ekim 2016 (1) Ağustos 2016 (2) Temmuz 2016 (2) Şubat 2016 (1) Kasım 2015 (2) Ekim 2015 (1) Temmuz 2015 (2) Haziran 2015 (1) Mayıs 2015 (1) Nisan 2015 (1) Şubat 2015 (2) Ocak 2015 (4) Aralık 2014 (2) Kasım 2014 (5) Ekim 2014 (8) Eylül 2014 (9) Ağustos 2014 (4) Temmuz 2014 (4) Haziran 2014 (2) Mayıs 2014 (2) Nisan 2014 (2) Mart 2014 (2) Şubat 2014 (3) Ocak 2014 (1) Aralık 2013 (2) Kasım 2013 (1) Ekim 2013 (2) Eylül 2013 (2) Ağustos 2013 (3) Temmuz 2013 (3) Haziran 2013 (6) Mayıs 2013 (2) Nisan 2013 (2) Mart 2013 (3) Şubat 2013 (4) Ocak 2013 (1) Aralık 2012 (2) Kasım 2012 (2) Ekim 2012 (3) Eylül 2012 (5) Ağustos 2012 (3) Temmuz 2012 (6) Haziran 2012 (4) Mayıs 2012 (4) Nisan 2012 (1) Mart 2012 (2) Şubat 2012 (1) Ocak 2012 (3) Aralık 2011 (3) Kasım 2011 (4) Ekim 2011 (4) Ağustos 2011 (1) Temmuz 2011 (1)