Jackson JSON: usare l’annotazione @JsonPropertyOrder per definire l’ordine di serializzazione delle proprietà

Nei commenti ad un precedente articolo un lettore ha chiesto supporto per sapere come fare, con la libreria Jackson, a personalizzare l’ordine con cui le proprietà di un oggetto compaiono nella stringa risultante dalla sua serializzazione JSON. In particolare, nel suo caso, voleva modificare l’ordine di default applicato alla serializzazione di un oggetto di una classe che ne estende un’altra. Il metodo che vedremo però va bene, in generale, quando si ha necessità di stabilire un preciso ordine di serializzazione delle proprietà.

Per un’introduzione a libreria Jackson e al suo utilizzo rimando all’articolo “Serializzazione e deserializzazione JSON di oggetti Java con Jackson: un esempio concreto“.

Iniziamo quindi a ricreare lo scenario descritto dal lettore del blog, creando due classi ClassB e ClassA con la seconda che eredita dalla prima. Per il nostro esempio usiamo Eclipse come IDE e creiamo un progetto Maven, che ci permetterà di aggiungere facilmente le librerie di Jackson come dipendenze.

Una volta creato il progetto, aggiungiamo il package “pojo” all’interno del quale creiamo le due classi:
Esempio JsonOrderProperty classi POJO da serializzare

Il codice delle due classi Java sarà il seguente:

public class ClassB {

	private String property1;
	private String property2;
	private String property3;

	public ClassB() {
		this.property1 = "Davis";
		this.property2 = "Molinari";
		this.property3 = "www.davismol.net";
	}
	
	public String getProperty1() {
		return property1;
	}
	public void setProperty1(String property1) {
		this.property1 = property1;
	}
	public String getProperty2() {
		return property2;
	}
	public void setProperty2(String property2) {
		this.property2 = property2;
	}
	public String getProperty3() {
		return property3;
	}
	public void setProperty3(String property3) {
		this.property3 = property3;
	}
}
public class ClassA extends ClassB {
	
	private int id;
	private String name;
		
	public ClassA( int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
}

Una volta create le due classi per gli oggetti che serializzeremo, andiamo ad aggiungere nel pom.xml le dipendenze Maven necessarie per utilizzare le funzionalità di Jackson che ci servono per questo esempio.
In particolare aggiungiamo jackson-core e jackson-databind:

	<dependencies>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.8.4</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.4</version>
		</dependency>
	</dependencies>

Esempio Jackson JsonOrderProperty dipendenze Maven
Fatto questo, definiamo una classe che conterrà il main in cui creeremo un’instanza della classe figlia ClassA che eredita da ClassB e in cui effettueremo la serializzazione
dell’oggetto, stampandone il risultato nella console di output. Chiamiamo questa classe JSONOrderExample e il suo contenuto sarà il seguente:

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import pojo.ClassA;

public class JSONOrderExample {

	public static void main(String[] args) {

        ObjectMapper mapper = new ObjectMapper();

        ClassA ca = new ClassA(1, "User1");

        try {
            mapper.writeValue(System.out, ca);
        }
        catch (JsonGenerationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (JsonMappingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

A questo punto non ci resta che provare ad eseguire l’applicazione. Il risultato che otteniamo, come ci aspettavamo, è il seguente:

{"property1":"Davis","property2":"Molinari","property3":"www.davismol.net","id":1,"name":"User1"}

Come possiamo vedere le proprietà vengono serializzare mettendo per prime quelle della classe padre e a seguire quelle della sottoclasse che eredita da essa.
Esempio Jackson JsonOrderProperty risultato default
Ora il nostro obiettivo, come richiesto nel commento dal lettore del blog è di modificare questo ordine di default e stabilire un ordine personalizzato facendo in modo, nel caso specifico, che le proprietà dell’oggetto della sottoclasse compaiano prima di quelle della classe base.
Per farlo dobbiamo utilizzare un’annotazione messa a disposizione da Jackson: @JsonPropertyOrder

@JsonPropertyOrder è un’annotazione da utilizzare a livello di classe e prende come proprietà una lista di campi che determina l’ordine in cui i campi saranno presenti nella stringa risultante dalla serializzazione JSON dell’oggetto.

Nel nostro caso, per ottenere il risultato desiderato dal lettore, dobbiamo annotare la classe ClassA in questo modo:

@JsonPropertyOrder({ "id", "name", "property1", "property2", "property3" })

Il codice completo della classe diventa quindi:


import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonPropertyOrder({ "id", "name", "property1", "property2", "property3" })
public class ClassA extends ClassB {
	
	private int id;
	private String name;
		
	public ClassA( int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	
	// GETTERS e SETTERS OMESSI PER SEMPLICITA'
	
}

Esempio Jackson JsonOrderProperty annotazione sulla classe

Proviamo quindi ad eseguire nuovamente la nostra applicazione. Il risultato che otteniamo in questo caso è il seguente:

{"id":1,"name":"User1","property1":"Davis","property2":"Molinari","property3":"www.davismol.net"}

Esempio Jackson JsonOrderProperty risultato proprietà ordinate
Come possiamo vedere il risultato ottenuto è esattamente quello desiderato; le proprietà “id” e “name” della sottoclasse ClassA compaiono infatti prima delle proprietà della classe base ClassB nella stringa risultante dalla serializzazione JSON dell’oggetto.

Leggi anche:

Il codice completo dell’esempio è scaricabile qui:

This entry was posted in $1$s. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *