• Cum. May 20th, 2022

Gson Kütüphanesi İle Java’dan Json’a ve Json’dan Java’ya Dönüşüm Yapma

Merhabalar arkadaşlar.

Bu yazıda sizlere Java kullanarak yazdığımız uygulamarda Java nesnesinden JSON’a ve JSON’dan Java nesnesine kolaylıkla dönüşüm yapmamızı sağlayan bir kütüphane olan GSON kütüphanesini size anlatmaya çalışacağım.

Öncelikle bu yazıdaki uygulamanın kaynak koduna https://github.com/ilkgunel/GsonExample adresi üzerinden ulaşabilirsiniz.

Şimdi IDE’nizde bir Maven projesi açın ya da isterseniz yukarıdaki projeyi indirip IDE’nizde açın. Bu yazı için Eclispe IDE kullanıyor olacağım. Projeyi açtıktan sonra pom.xml dosyanıza şu bağımlılık kodu ekleyin:

<dependencies>
	<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
	<dependency>
		<groupId>com.google.code.gson</groupId>
		<artifactId>gson</artifactId>
		<version>2.8.0</version>
	</dependency>
</dependencies>

Eğer herhangi bir ayarı değiştirilmedi ise Eclipse IDE pom.xml’i kaydettiğimizde kütüphaneyi indirip classpath’e koyar.

Bu yazı için kullanacağımız POJO sınıfımız şöyle olacak:

package com.ilkaygunel.gson;

public class Person {
	private String id;
	private String name;
	private String surname;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSurname() {
		return surname;
	}

	public void setSurname(String surname) {
		this.surname = surname;
	}

}

Person sınıfımız gördüğünüz gibi son derece basit. id, name, surname alanları ve onların get set metotları yer alıyor.

Akabinde FromJavaToJson adında bir class oluştalım ve kodunu şöyle düzenleyelim:

package com.ilkaygunel.gson;

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder;

public class FromJavaToJson {
    public static void main(String[] args) {
        Person person = new Person();
        person.setId("1");
        person.setName("Hakan Çetin");
        person.setSurname("Kısa");

        Gson gsonBuilder = new GsonBuilder().create();
        System.out.println(gsonBuilder.toJson(person));
    }
}

FromJavaToJson sınıfındaki main metodu içerisinde öncelikle Person sınıfından bir obje oluşturup set metotları ile alanlarına değer tanımları yapıyoruz. Akabinde

Gson gsonBuilder = new GsonBuilder().create();

satırı ile JSon’dan Java’ya ve Java’dan Json’a dönüşüm yapma yeteneği olan gsonBuilder objemizi oluşturuyoruz.

Son olarak gsonBuilder nesnesi vasıtası ile çağırdığımız toJson metodune bu person nesnesini parametre olarak verip çıkan sonucu ekrana yazdırıyoruz.

Bu sınıfı çalıştırdığımızda gördüğünüz gibi bir Json objesi elde ettik.

Yukarıdaki örnekte bir objeyi JSon’a çevirdik. Şimdi birden fazla objeyi içeren bir Json nasıl oluşturabiliriz ona bakalım.

FromJavaToJson sınıfını şu şekilde güncelleyelim:

package com.ilkaygunel.gson;

import com.google.gson.Gson; 
import java.util.ArrayList;
import java.util.List;

public class FromJavaToJson {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<Person>();

        Person person = new Person();
        person.setId("1");
        person.setName("Hakan Çetin");
        person.setSurname("Kısa");

        Person person2 = new Person();
        person2.setId("2");
        person2.setName("Mehmet");
        person2.setSurname("Taşgit");

        Person person3 = new Person();
        person3.setId("3");
        person3.setName("Mustafa");
        person3.setSurname("Ekicim");

        personList.add(person);
        personList.add(person2);
        personList.add(person3);

        Gson gson = new Gson();
        String json = gson.toJson(personList);
        System.out.println(json);
    }
}

Önceki örnekten farklı olarak burada toJson metodunu kullanacağımız nesneyi GsonBuilder().create() üzerinden değil direk new Gson diyerek elde ediyoruz. Fakat bu değişimin listeyi ya da birden fazla objeyi Json’a çevirme ile ilgisi yok. Bunu sadece bu şekilde de kullanabilirsiniz demek için buraya aldım. Yoksa new GsonBuilder().create(); ifadesi de aynı işi görüyor.

Kodu çalıştırdığımızda konsol çıktısı şöyle oluyor:

Şimdi bir Json dosyasından dönüşüm nasıl yaparız ona değinelim.

Az önceki Json çıktısını https://jsonformatter.curiousconcept.com/ adresi üzerinden formatlayalım. Uzantısı .json olan bir dosya oluşturup formatladığımız Json’ı içine kopyalayalım. Benim dosyam şu şekilde:

[
   {
      "id":"1",
      "name":"Hakan Çetin",
      "surname":"Kısa"
   },
   {
      "id":"2",
      "name":"Mehmet",
      "surname":"Taşgit"
   },
   {
      "id":"3",
      "name":"Mustafa",
      "surname":"Ekicim"
   }
]

Yukarıdaki Json’dan okuma yaparak Java objelerine çevirecek FromJsonToJava sınıfımız da şu şekilde:

package com.ilkaygunel.gson;

import java.io.FileNotFoundException; 
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;

public class FromJsonToJava {
	public static void main(String[] args) {
		List<Person> personList = new ArrayList<Person>();
		try {
			FileReader fileReader = new FileReader("src/main/resources/jsonFile.json");
			Gson gson = new Gson();
			JsonParser parser = new JsonParser();
			JsonArray jsonArray = parser.parse(fileReader).getAsJsonArray();
			for (int i = 0; i < jsonArray.size(); i++) {
				Person person = gson.fromJson(jsonArray.get(i), Person.class);
				personList.add(person);
			}
		} catch (FileNotFoundException e) {
			System.out.println("Bir Hata Meydana Geldi! Hata:"+e);
		}
		
		for (Person p:personList) {
			System.out.println(p.getId()+" "+p.getName()+" "+p.getSurname());
		}
	}
}

Sınıfımızı inceleyelim.

  • Öncelikle Json dosyasından okuma yapıp Person objelerini tutacak bir personList nesnesi oluşturuyoruz.
  • Java’da dosya okuma işlemlerinden hatırlayacağınız bir FileReader nesnesini json dosyasını parametre vererek oluşturuyoruz.
  • fromJson metodunu kullanacağımız bir Gson nesnesi oluşturuyoruz.
  • Json dosyası üzerinde parçalama yapacak bir JsonArray nesnesi oluşturuyoruz.
  • Json dosyamız birden person objesine karşılık gelecek bilgi tuttuğu için bir JsonArray tanımlıyoruz ve bu JsonArray’i parser nesnesinin parse metodu ile oluşturuyoruz. Bu parse metoduna parçalanacak Json ile ilgili bir şey verilmesi lazım, biz de fileReader nesnesini veriyoruz. Son olarak getAsJsonArray JsonArray elde ediyoruz.
  • Elde ettiğimiz JsonArray’in size’ı kadar dönecek bir for döngüsü oluşturup içinde Person nesneleri oluşturuyoruz. Person nesnelerini gson nesnesindeki fromJson metodunu kullanarak oluşturuyoruz. fromJson metoduna iki parametre veriyoruz. Birincisi Java objesine çevirilecek Json objesi, ikincisi ise hangi sınıfa göre çevirim yapılacağı. Birinci JsonArray’in ilgili gözündeki parametre olarak veriyoruz zira JsonArray’in herbir gözü bir Json objesidir. İkinci parametre de bildiğiniz gibi Person sınıfıdır.
  • Kodun son aşamasında ise elde ettiğimiz listeyi konsola yazdırıyoruz.

Kodu çalıştırınca çıktımız şu şekilde:

Eğer Json dosyamız şu şekilde tek bir person objesine denk gelen bir veri tutuyorsa kodu şu şekilde güncelleyebiliriz:

{
   "id":"1",
   "name":"Emre",
   "surname":"Uysal"
}
try {
		FileReader fileReader = new FileReader("src/main/resources/jsonFile2.json");
		Gson gson = new Gson();
		Person person = gson.fromJson(fileReader, Person.class);
		System.out.println(person.getId() + " " + person.getName() + " " + person.getSurname());
	} catch (FileNotFoundException e) {
		System.out.println("Bir Hata Meydana Geldi! Hata:" + e);
	}

Eğer okuma yapacağımız JSON dosyasındaki alanların isimleri ile JSON dosyasını temsil eden Java sınıfındaki alanların isimlerinin farklı olmasını istersek ne yapmalıyız?

GSON kütüphanesi herhangi bir tanımlama yapılmadığında (az sonra göstereceğim notasyon kullanılmadığında) elimizdeki JSON ile Java sınıfındaki tüm alanların isimlerinin aynı olduğu varsayımını yapıyor ve nesne oluşturacağı zaman da bu şekilde oluşturuyor. Eğer GSON bu varsayımı yaparken JSON’daki alanlar ile Java sınıfındaki alanlar farklı ise GSON size alanları boş bir nesne oluşturup veriyor. Yani JSON’dan okuduğu değerleri alanlara kaydetmiyor, daha doğrusu kaydedemiyor çünkü alanları eşleştiremiyor.

Örneğin JSON dosyasına Name şeklinde bir alan varken biz Java sınıfı içinde bunu String Name; şeklinde tanımlamamalıyız, yine String name şeklinde kullanmalıyız. Bu durumda da JSON’daki Name ile Java sınıfındaki name isim olarak eşleşmediği için GSON objeyi oluştururken değer yüklemesi yapamaıyor. İşte bu durumda imdadımıza @SerializedName notasyonu yetişiyor. Eğer JSON içindeki alanı Java sınıfı içinde başka bir isimle temsil etmek istersek bu notasyon vasıtası ile tanımlama yapabiliriz. Şimdi nasıl kullanıldığına bakalım.

Önceki JSON’daki alan isimlerinin baş harflerini büyük yaparak JSON’ımızı şu hale getirelim:

[
   {
      "Id":"1",
      "Name":"Hakan Çetin",
      "Surname":"Kısa"
   },
   {
      "Id":"2",
      "Name":"Mehmet",
      "Surname":"Taşgit"
   },
   {
      "Id":"3",
      "Name":"Mustafa",
      "Surname":"Ekicim"
   }
]

Bu JSON’ı temsil edecek Java sınıfımız da şu şekilde olacak:

package com.ilkaygunel.gson;

import com.google.gson.annotations.SerializedName;

public class SerializedPerson {
	@SerializedName("Id")
	private String id;

	@SerializedName("Name")
	private String name;

	@SerializedName("Surname")
	private String surname;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSurname() {
		return surname;
	}

	public void setSurname(String surname) {
		this.surname = surname;
	}
}

SerializedPerson sınıfı içerisinde alanlarımız @SerializedName notasyonu ile işaretli. Bu notasyona biz JSON’ımızın içindeki alanın ismini veriyoruz. Böylece GSON JSON ile Java sınıfı alanları arasındaki eşleştirmeleri en doğru şekilde yapmaya mukabil oluyor. Örneğin

@SerializedName("Name")
private String name;

kodu ile GSON kütüphanesi dönüşüm ve nesne oluşturma işlemi sırasında JSON içerisinde Name ismindeki alanı Java sınıfı içindeki String name alanına dolduracaktır.

Main metodunu barındıran kodumuzun yeni hali de şöyle olacaktır:

package com.ilkaygunel.gson;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;

public class FromJsonToJava {
	public static void main(String[] args) {
		List<SerializedPerson> serializedPersons = new ArrayList<SerializedPerson>();
		try {
			FileReader fileReader = new FileReader("src/main/resources/jsonForSerialized.json");
			Gson gson = new Gson();
			JsonParser parser = new JsonParser();
			JsonArray jsonArray = parser.parse(fileReader).getAsJsonArray();
			for (int i = 0; i < jsonArray.size(); i++) {
				SerializedPerson serializedPerson = gson.fromJson(jsonArray.get(i), SerializedPerson.class);
				serializedPersons.add(serializedPerson);
			}
		} catch (FileNotFoundException e) {
			System.out.println("Bir Hata Meydana Geldi! Hata:" + e);
		}

		for (SerializedPerson p : serializedPersons) {
			System.out.println(p.getId() + " " + p.getName() + " " + p.getSurname());
		}
	}
}

Yazının üst kısımlarında bu metoda dair bilgiler verdiğim için tekrar girmiyorum arkadaşlar.

Konsol çıktısı da şöyle:


Gördüğünüz gibi JSON’daki alan isimleri ile Java sınıfındaki alan isimleri farklı olunca bu şekilde okuma yapabiliyoruz.
Bu yazıda anlatacaklarım bu kadar arkadaşlar. Başka bir yazıda görüşene kadar sağlıcakla kalın.
Görüşmek üzere.

Selam ve Sevgilerimle

Merhaba! Ben İlkay Günel :) İstanbul Üniversitesi Bilgisayar Mühendisliği 2016 mezunuyum. Güncel olarak Paycore'da SoftPOS projesinde Java Developer olarak çalışmaktayım. Büyük oranda Java teknolojileri ile uğraşıp kendimi geliştirmeye çalışıyorum ve bu mecrada öğrendiklerimi sizle paylaşmaya da çabalıyorum :) Hakkımda biraz daha detaylı bilgi için: http://www.ilkaygunel.com/about/

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir