Reduktion af JSON-datastørrelse

1. Introduktion

Java-applikationer bruger ofte JSON som et almindeligt format til afsendelse og modtagelse af data. Desuden bruges det som en serialiseringsprotokol til lagring af data. Med mindre JSON-datastørrelser bliver vores applikationer billigere og hurtigere.

I denne vejledning ser vi på forskellige måder at reducere størrelsen på JSON i vores Java-applikationer.

2. Domænemodel og testdata

Lad os oprette en domænemodel til en Kunde med nogle kontaktdata:

offentlig klasse kunde {privat lang id; privat streng fornavn; privat streng efternavn; privat String street; private String postalCode; private String by; privat strengstat; private String-telefonnummer; privat streng e-mail;

Bemærk, at alle felter er obligatoriske bortset fra telefonnummer og e-mail.

For at kunne teste forskelle i JSON-datastørrelse korrekt har vi brug for mindst et par hundrede Kunde tilfælde. De skal have forskellige data for at gøre vores tests mere naturtro. Webstedet til generering af data mockaroo hjælper os her. Vi kan oprette 1.000 JSON-dataposter der gratis, i vores eget format og med autentiske testdata.

Lad os konfigurere mockaroo til vores domænemodel:

Her er nogle ting, du skal huske på:

  • Det er her, vi specificerede feltnavne
  • Her valgte vi datatyperne for vores felter
  • 50% af telefonnumrene er tomme i mock-dataene
  • 30% af e-mail-adresserne er også tomme

Alle kodeeksemplerne nedenfor bruger de samme data fra 1.000 kunder fra mockaroo. Vi bruger fabriksmetoden Customer.fromMockFile () at læse den fil og gøre den til Kunde genstande.

Vi bruger Jackson som vores JSON-behandlingsbibliotek.

3. JSON-datastørrelse med Jackson-standardindstillinger

Lad os skrive et Java-objekt til JSON med standardindstillingerne for Jackson:

Kunde [] kunder = Customer.fromMockFile (); ObjectMapper-kortlægger = ny ObjectMapper (); byte [] feedback = mapper.writeValueAsBytes (kunder); 

Lad os se mock-dataene for det første Kunde:

{"id": 1, "firstName": "Horatius", "lastName": "Strognell", "street": "4848 New Castle Point", "postalCode": "33432", "city": "Boca Raton" , "state": "FL", "phoneNumber": "561-824-9105", "email": "[email protected]"}

Når du bruger standard Jackon-indstillinger, er JSON-databyte-arrayet med alle 1.000 kunder 181,0 KB i størrelse.

4. Komprimering med gzip

Som tekstdata komprimeres JSON-data pænt. Derfor gzip er vores første mulighed for at reducere JSON-datastørrelsen. Desuden kan den automatisk anvendes i HTTP, den fælles protokol til afsendelse og modtagelse af JSON.

Lad os tage den JSON, der er produceret med Jackson-standardindstillingerne, og komprimere den med gzip. Dette resulterer i 45,9 KB, kun 25,3% af den oprindelige størrelse. Så hvis vi kan aktivere gzip komprimering gennem konfiguration, skærer vi JSON-datastørrelsen ned med 75% uden ændringer i vores Java-kode!

Hvis vores Spring Boot-applikation leverer JSON-data til andre tjenester eller front-ender, aktiverer vi det gzip komprimering i Spring Boot-konfigurationen. Lad os se en typisk kompressionskonfiguration i YAML-syntaks:

server: komprimering: aktiveret: ægte mime-typer: tekst / html, tekst / almindelig, tekst / css, applikation / javascript, applikation / json min-respons-størrelse: 1024 

Først aktiverede vi komprimering generelt ved at indstille aktiveret som sandt. Derefter aktiverede vi specifikt JSON-datakomprimering ved at tilføje ansøgning / json til listen over mime-typer. Endelig bemærk, at vi har sat min-respons-størrelse til 1.024 byte lange. Dette skyldes, at hvis vi komprimerer korte mængder data, kan vi producere større data end originalen.

Ofte leverer proxyer som NGINX eller webservere som Apache HTTP Server JSON-data til andre tjenester eller frontendere. Konfiguration af JSON-datakomprimering i disse værktøjer ligger uden for omfanget af denne vejledning.

En tidligere tutorial om gzip fortæller os det gzip har forskellige kompressionsniveauer. Vores kodeeksempler bruger gzip med standard Java-komprimeringsniveau. Spring Boot, proxies eller webservere kan få forskellige komprimeringsresultater for de samme JSON-data.

Hvis vi bruger JSON som serialiseringsprotokol til at gemme data, skal vi selv komprimere og dekomprimere dataene.

5. Kortere feltnavne i JSON

Det er en bedste praksis at bruge feltnavne, der hverken er for korte eller for lange. Lad os udelade dette for demonstrations skyld: Vi bruger felttegn med enkelt tegn i JSON, men vi ændrer ikke Java-feltnavne. Dette reducerer JSON-datastørrelsen, men mindsker JSON-læsbarheden. Da det også vil kræve opdateringer til alle tjenester og frontend, bruger vi sandsynligvis kun disse korte feltnavne, når vi lagrer data:

{"i": 1, "f": "Horatius", "l": "Strognell", "s": "4848 New Castle Point", "p": "33432", "c": "Boca Raton" , "a": "FL", "o": "561-824-9105", "e": "[email protected]"}

Det er let at ændre JSON-feltnavne med Jackson, mens Java-feltnavne efterlades intakt. Vi bruger @JsonProperty kommentar:

@JsonProperty ("p") privat streng postkode; 

Brug af feltnavne med et enkelt tegn fører til data, der er 72,5% af den oprindelige størrelse. Desuden bruger gzip vil komprimere det til 23,8%. Det er ikke meget mindre end de 25,3%, vi fik ved blot at komprimere de originale data med gzip. Vi er altid nødt til at kigge efter en passende cost-benefit-relation. At miste læsbarhed for en lille gevinst i størrelse kan ikke anbefales i de fleste scenarier.

6. Serialisering til en matrix

Lad os se, hvordan vi yderligere kan reducere JSON-datastørrelsen ved helt at udelade feltnavne. Vi kan opnå dette ved at gemme en kunder array i vores JSON. Bemærk, at vi også reducerer læsbarheden. Og vi bliver også nødt til at opdatere alle de tjenester og frontend, der bruger vores JSON-data:

[1, "Horatius", "Strognell", "4848 New Castle Point", "33432", "Boca Raton", "FL", "561-824-9105", "[email protected]"] 

Opbevaring af Kunde som en matrix fører til output, der er 53,1% af den oprindelige størrelse og 22,0% med gzip kompression. Dette er vores bedste resultat hidtil. Alligevel er 22% ikke signifikant mindre end de 25,3%, vi fik ved blot at komprimere de originale data med gzip.

For at serieisere en kunde som en array er vi nødt til at tage fuld kontrol over JSON-serialisering. Se igen til vores Jackson-tutorial for flere eksempler.

7. Ekskluderende nul Værdier

Jackson og andre JSON-behandlingsbiblioteker håndterer muligvis ikke JSON nul værdier korrekt, når du læser eller skriver JSON. For eksempel skriver Jackson en JSON nul værdi som standard, når den møder en Java nul værdi. Derfor det er en god praksis at fjerne tomme felter i JSON-data. Dette efterlader initialiseringen af ​​tomme værdier til hvert JSON-behandlingsbibliotek og reducerer JSON-datastørrelsen.

I vores mock-data indstiller vi 50% af telefonnumrene og 30% af e-mail-adresserne som tomme. At udelade disse nul værdier reducerer vores JSON-datastørrelse til 166,8 kB eller 92,1% af den oprindelige datastørrelse. Derefter, gzip komprimering falder til 24,9%.

Nu, hvis vi kombinerer ignorering nul værdier med de kortere feltnavne fra det foregående afsnit, så får vi større besparelser: 68,3% af den oprindelige størrelse og 23,4% med gzip.

Vi kan konfigurere udeladelsen af nul værdifelter i Jackson pr. klasse eller globalt for alle klasser.

8. Ny domæneklasse

Vi opnåede den mindste JSON-datastørrelse hidtil ved at serieisere den til en matrix. En måde at reducere det endnu mere på er en ny domænemodel med færre felter. Men hvorfor skulle vi gøre det?

Lad os forestille os en front-end for vores JSON-data, der viser alle kunder som en tabel med to kolonner: navn og gadenavn. Lad os skrive JSON-data specifikt til denne front-end:

{"id": 1, "name": "Horatius Strognell", "address": "4848 New Castle Point, Boca Raton FL 33432"}

Bemærk hvordan vi sammenkædede navnefelterne til navn og adressefelterne i adresse. Også vi udeladt e-mail og telefonnummer.

Dette skulle producere meget mindre JSON-data. Det sparer også frontenden fra sammenkædning af Kunde felter. Men på ulempen er dette par vores back-end tæt til front-end.

Lad os oprette en ny domæneklasse Kundeslim til denne front-end:

offentlig klasse CustomerSlim {privat lang id; privat strengnavn; privat strengadresse;

Hvis vi konverterer vores testdata til dette nye Kundeslim domæneklasse reducerer vi den til 46,1% af den oprindelige størrelse. Det bruger standard Jackson-indstillingerne. Hvis vi bruger gzip det går ned til 15,1%. Dette sidste resultat er allerede en betydelig gevinst i forhold til det tidligere bedste resultat på 22,0%.

Dernæst, hvis vi også bruger felttegn med et tegn, får vi os ned til 40,7% af den oprindelige størrelse med gzip yderligere reduceret dette til 14,7%. Dette resultat er kun en lille gevinst på over 15,1%, vi nåede med Jackson-standardindstillingerne.

Ingen felter i Kundeslim er valgfri, så udeladelse af tomme værdier har ingen indflydelse på JSON-datastørrelsen.

Vores sidste optimering er serialisering af en matrix. Ved at serialisere Kundeslim til en matrix opnår vi vores bedste resultat: 34,2% af den oprindelige størrelse og 14,2% med gzip. Så selv uden komprimering fjerner vi næsten to tredjedele af de originale data. Og komprimering krymper vores JSON-data til kun en syvendedel af den oprindelige størrelse!

9. Konklusion

I denne artikel så vi først, hvorfor vi har brug for at reducere JSON-datastørrelser. Derefter lærte vi forskellige måder at reducere denne JSON-datastørrelse på. Endelig lærte vi, hvordan vi yderligere reducerer JSON-datastørrelsen med en domænemodel, der er tilpasset en front-end.

Den komplette kode er som altid tilgængelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found