Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Parsing JSON semplice con google GSON

Breve ed essenziale introduzione alla libreria di google per la serializzazione GSON
Breve ed essenziale introduzione alla libreria di google per la serializzazione GSON
Link copiato negli appunti

In questo articolo daremo una occhiata ai concetti principali di Gson, una libreria sviluppata da Google, che rende incredibilmente semplice e veloce la conversione tra gli oggetti Java e la loro rappresentazione JSON.

Originariamente la libreria fu creata per essere utilizzata esclusivamente per l'uso interno nei progetti Google, in seguito è stata resa disponibile pubblicamente per gli sviluppatori, e può quindi essere utilizzata nelle nostre applicazioni, in alternativa ad altre librerie analoghe (come ad esempio Jettison o Jabsorb, ad esempio.
Sul sito ufficiale del progetto, è possibile scaricare l’ultima versione rilasciata (attualmente la 2.3).

Con l'affermazione del Web 2.0, è ormai una esigenza comune quella di serializzare e deserializzare gli oggetti in formato JSON nella maniera più semplice e standard possibile: pensiamo ad esempio alle risorse consumate su servizi REST, così come a formati di scambio per applicazioni mashup.

Le caratteristiche principali di GSON sono in particolare le seguenti:

  • Semplice e veloce da utilizzare.
  • Indipendente dai file sorgenti. Quasi tutte le librerie analoghe, invece, richiedono l'inserimento di alcune annotazioni nei bean che occorre serializzare. Questa procedura è improponibile se non si ha a disposizione il codice sorgente, personalizzabile.
  • È possibile creare degli adapter personalizzati per definire la modalità di serializzazione degli oggetti.
  • Ampio supporto di Java Generics.

Un esempio pratico

Per i nostri esempi, creiamo un semplice bean User, con alcune proprietà.

package it.lucasantaniello.tutorial.gson;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private Integer id;
private String name;
private String surname;
private Date birtday;
public Integer getId() {
	return id;
}
public void setId(Integer 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;
}
public Date getBirtday() {
	return birtday;
}
public void setBirtday(Date birtday) {
	this.birtday = birtday;
}
@Override
public String toString() {
	return String.format("User [id=%s, name=%s, surname=%s, birtday=%s]", id, name, surname, birtday);
}
}

serializzazione

Serializzare il nostro oggetto è semplicissimo. È necessario creare un'istanza della classe com.google.gson.Gson ed invocare il metodo toJson() che riceve in ingresso un Object.

Nel primo caso passiamo un oggetto User, nel secondo caso una lista di oggetti User. In entrambi i casi GSON restituisce una stringa che rappresenta la risorsa in esame: nel primo caso un singolo oggetto User in formato JSON, nel secondo caso, una lista di oggetti User in formato JSON.

User user = new User();
user.setId(1);
user.setName("Luca");
user.setSurname("Santaniello");
user.setBirtday(getDate("06-04-1981", "dd-MM-yyyy"));
User user2 = new User();
user2.setId(2);
user2.setName("Pocho");
user2.setSurname("Lavezzi");
user2.setBirtday(getDate("10-10-1986", "dd-MM-yyyy"));
List<User> users = new ArrayList<User>();
users.add(user1);
users.add(user2);
Gson gson = new Gson();
String userJson = gson.toJson(user);
System.out.println(userJson);
String usersJson = gson.toJson(users);
System.out.println(usersJson);

Ed ecco il risultato del nostro primo test.

userJson = {
	"id":1,
	"name":"Luca",
	"surname":"Santaniello",
	"birtday":"Apr 6, 1981 12:00:00 AM"
}
usersJson = [
{
	"id":1,
	"name":"Luca",
	"surname":"Santaniello",
	"birtday":"Apr 6, 1981 12:00:00 AM"
}, {
	"id":2,
	"name":"Pocho",
	"surname":"Lavezzi",
	"birtday":"Oct 10, 1986 12:00:00 AM"
}
]

deserializazione

Adesso ipotizziamo di avere la nostra stringa JSON e dover deserializzarla in un oggetto.

Anche in questo caso GSON mette a disposizione un unico metodo da invocare fromJson(), che riceve in ingresso la stringa json e la classe nella quale deserializzarla.

Nel caso in cui sia necessario deserializzare una Lista occorre dichiarare il tipo di oggetti contenuti nella lista utilizzando la classe com.google.gson.reflect.TypeToken.

Come è possibile notare, non è possibile deserializzare liste che contengono oggetti di natura differente.

String jsonUser = "{"id":1,"name":"Luca","surname":"Santaniello", "birthday":"Apr 6, 1981 12:00:00 AM"}";
Gson gson = new Gson();
User user = gson.fromJson(jsonUser, User.class);
System.out.println(user);
String jsonUsers = "[{"id":1,"name":"Luca","surname":"Santaniello"},{"id":2,"name":"Pocho","surname":"Lavezzi"}]";
Type collectionType = new TypeToken<Collection<User>(){}.getType();
Collection<User> users = gson.fromJson(jsonUsers, collectionType);
for (User u : users) {
	System.out.println(u);
}

Potrebbe sorgere l’esigenza di voler definire un formato particolare per la data, ad esempio dd/MM/yyyy.

Ipotizziamo che la nostra stringa json sia la seguente:

{"id":1,"name":"Luca","surname":"Santaniello", "birtday":"06-04-1981"}

Se lanciamo nuovamente il test otteniamo un'eccezione di tipo ParseException. Di default infatti, GSON utilizza il formato standard delle date (ad esempio: Apr 6, 1981 10:20:00 AM):

ParseException
Caused by: java.text.ParseException: Unparseable date: "06-04-1981"
	at java.text.DateFormat.parse(DateFormat.java:337)
	at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:79)
	... 10 more

Per risolvere questo genere di problemi, Gson ci mette a disposizione la classe GsonBuilder, mediante la quale è possibile definire le impostazioni del serializzatore ed impostare alcune proprietà, tra le quali il formato della data.

String jsonUser = "{"id":1,"name":"Luca","surname":"Santaniello", "birtday":"06-04-1981"}";
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("dd-MM-yyyy");
Gson gson = gsonBuilder.create();
User user = gson.fromJson(jsonUser, User.class);
System.out.println(user);

GsonBuilder naturalmente può essere utilizzato sia in fase di serializzazione che in fase di deserializzazione.

adapter personalizzati

È possibile, inoltre, definire degli Adapter personalizzati. Per definire il nostro custom adapter è necessario creare una classe che implementa JsonSerializer e JsonDeserializer per serializzare e deserializzare l'oggetto.

Ipotizziamo di voler stabilire la modalità di serializzazione e deserializzazione di tutti gli oggetti GregorianCalendar. Di default Gson serializza un GregorianCalendar con una stringa di questo tipo:

"birtdayCalendar":{
	"year":1981,
	"month":3,
	"dayOfMonth":6,
	"hourOfDay":0,
	"minute":0,
	"second":0
}

e ipotizziamo di volerlo stampare invece in questo modo:

"birtdayCalendar":{“06-04-1981”}

Creiamo il nostro adapter ed implementiamo la logica dei metodi serialize e deserialize.

package it.lucasantaniello.tutorial.gson;
public class CalendarAdapter
	implements JsonSerializer<Calendar>,
	JsonDeserializer<Calendar> {
	private String dateFormat;
	public CalendarAdapter(String dateFormat) {
		this.dateFormat = dateFormat;
	}
	@Override
	public JsonElement serialize(Calendar calendar,
		Type type, JsonSerializationContext context) {
		String str = null;
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		if (calendar != null) {
			str = sdf.format(calendar.getTime());
		}
		return new JsonPrimitive(str);
	}
	@Override
	public Calendar deserialize(JsonElement json,
		Type type, JsonDeserializationContext context)
		throws JsonParseException {
		String strDate = json.getAsString();
		Calendar calendar = null;
		try {
			calendar = Calendar.getInstance();
			DateFormat formatter = new SimpleDateFormat(dateFormat);
			Date date = (Date) formatter.parse(strDate);
			calendar.setTimeInMillis(date.getTime());
		} catch (ParseException e) {
			throw new JsonParseException("calendar parsing error");
		}
		return calendar;
	}
}

Per attivare il nostro adapter è necessario registrarlo utilizzando il GsonBuilder:

gsonBuilder.registerTypeAdapter(
	GregorianCalendar.class,
	new CalendarAdapter("dd-MM-yyyy")
);

Ti consigliamo anche