bloggers bloggers

Marco Napolitano
Messaggi: 79
Stelle: 0
Data: 17/02/22
Jader Jed Francia
Messaggi: 63
Stelle: 0
Data: 18/02/21
Paolo Gambetti
Messaggi: 2
Stelle: 0
Data: 11/11/19
Katia Pazzi
Messaggi: 1
Stelle: 0
Data: 27/06/19
Ezio Lombardi
Messaggi: 11
Stelle: 0
Data: 10/04/18
Chiara Mambretti
Messaggi: 25
Stelle: 0
Data: 27/02/17
Serena Traversi
Messaggi: 3
Stelle: 0
Data: 21/07/16
Francesco Falanga
Messaggi: 8
Stelle: 0
Data: 14/06/16
Antonio Musarra
Messaggi: 2
Stelle: 0
Data: 18/11/13
Simone Celli Marchi
Messaggi: 6
Stelle: 0
Data: 09/07/13
Indietro

Liferay 6.2 e la serializzazione deep delle entità via JSON

Recentemente stavo lavorando ad un progetto che consisteva nell'esporre dei metodi dello strato remoto dei servizi per essere consumati da un client REST.

Praticamente tutte le entità possedevano campi di tipo long che rappresentavano foreign key verso altre entità; pertanto all'interno delle varie classi *Impl dei modelli avevo definito altrettanti metodi getter per recuperare gli oggetti referenziati dalle foreign key. E fino a questo punto non c'era nulla di insolito...

Invocando però i metodi REST esposti mi sono accorto che alcune entità venivano serializzate in modalità shallow ossia presentavano unicamente i campi definiti nel file service.xml; altre entità invece venivano serializzate in modailtà deep ossia presentavano anche il contenuto di tutti gli oggetti restituiti dai metodi custom che avevo definito nelle classi *Impl.

L'unica differenza tra queste entità era che per le prime (modalità shallow) avevo definito remote-service="true" nel service.xml mentre per le seconde (modalità deep) avevo definito remote-service="false" dal momento che si trattava di semplici DTO che non dovevano avere uno strato di persistenza.

Indagando un pò ho scoperto che se un'entità viene definita con remote-service="true" allora l'attributo json-enabled viene messo di default a true; viceversa rimane a false.

Avere l'attributo json-enabled="true" significa che il Service Builder andrà ad annotare le classi *ModelImpl con @JSON(strict = true); questa annotation fa sì che solamente i campi dichiarati nel service.xml vengano serializzati, facendo quindi una serializzazione shallow. Peccato che nel caso opposto (ossia json-enabled="false"), in cui l'entità non dovrebbe supportare la serializzazione JSON, la supporta ugualmente ed addirittura in modalità deep! Sarà un bug o una feature?

Quindi come facciamo ad avere noi il controllo di quello che viene serializzato? Innanzitutto dobbiamo partire dal fatto che per essere serializzabile in formato JSON, un'entità deve avere json-enabled="true"; quindi le definiamo così:

<entity name="Entity1" remote-service="true" ...>
    ...
</entity>
<entity name="Entity2" remote-service="false" json-enabled="true" ...>
    ...
</entity>

Facendo in questo modo, come abbiamo già visto sopra, otterremo una semplice serializzazione shallow; ma se volessimo spingerci oltre dobbiamo dire al Service Builder quali metodi custom includere nella serializzazione. Quindi se nella classe Entity1Impl abbiamo definito dei metodi custom, sarò sufficiente annotarli con @JSON(include = true) ed il risultato di tali metodi verrà serializzato in formato JSON insieme al resto dell'entità.

Bella lì!

Commenti
Nessun commento. Vuoi essere il primo.