Converti JSON in XML Java utilizzando Gson e JAXB

โšก Riepilogo intelligente

Converti JSON in XML Java utilizzando Gson e JAXB tramite mappaping entrambi i formati sullo stesso annotato Java classi. Questo articolo definisce ciascun formato, imposta il progetto, decodifica l'XML con JAXB, scrive il JSON con Gson e inverte l'intero processo.

  • ๏ธ Struttura JSON: I dati vengono memorizzati come coppie chiave-valore racchiuse tra parentesi graffe, con virgole a separare ciascuna voce.
  • ๐Ÿท๏ธ Struttura XML: I dati vengono memorizzati in nodi annidati, dove ogni tag di apertura richiede un tag di chiusura corrispondente.
  • ๐Ÿ”— Modello condiviso: Un insieme di annotazioni Java Le classi fungono da ponte, in modo che nessuno dei due formati venga convertito direttamente nell'altro.
  • ๐Ÿ“ฅ Smantellamento: JAXB legge un file XML e restituisce un file popolato Java Albero degli oggetti attraverso la classe Unmarshaller.
  • ๐Ÿ“ค Streaming Write: Il Gson JsonWriter Emette JSON in modo incrementale tramite le chiamate beginObject, name, value e endObject.
  • ๐Ÿ”„ Reverse percorso: JsonReader ricostruisce gli oggetti a partire dal JSON, mentre JAXB Marshaller li riscrive in formato XML.
  • โš ๏ธ Nota di esecuzione: JAXB ha lasciato il JDK a Java 11, quindi la dipendenza jakarta.xml.bind deve essere aggiunta esplicitamente.

Convertire JSON in XML in Java

Cos'รจ JSON?

JSON รจ un'abbreviazione di JavaScript Object Notation (JSON) รจ un formato dati che segue regole comprensibili alla maggior parte dei linguaggi di programmazione. Possiamo facilmente salvarlo in un file o memorizzarlo in un database. Il formato JSON utilizza coppie chiave-valore per descrivere i dati.

Nell'esempio seguente, definiamo una stringa JSON che memorizza informazioni personali:

{
"username" : "guru99user",
"email" : "guru99user@mail.com"
}

La sintassi di JSON รจ quindi molto semplice. Ogni elemento di dati รจ composto da due parti, una chiave e un valore, che corrispondono al nome del campo e al suo valore all'interno di un record. Analizzando piรน a fondo, si possono seguire alcune regole di questo tipo:

  • La stringa JSON รจ racchiusa tra parentesi graffe {}.
  • Le chiavi JSON devono essere racchiuse tra virgolette doppie, e anche i valori stringa devono essere racchiusi tra virgolette.
  • Se i dati sono piรน numerosi (piรน coppie chiave => valore), utilizziamo le virgole (,) per separarli.
  • Le chiavi JSON devono essere composte da lettere, numeri o dal carattere di sottolineatura, senza spazi, e il primo carattere non deve essere un numero.

Cos'รจ l'XML?

XML sta per eXtensible Markup Language, proposto dal World Wide Web Consortium (https://www.w3.org/) per creare altri linguaggi di markup. Si tratta di un semplice sottoinsieme in grado di descrivere molti tipi diversi di dati, quindi รจ molto utile per la condivisione di dati tra sistemi.

I tag in XML spesso non sono predefiniti, ma vengono creati in base alle convenzioni dell'utente. XML introduce nuove funzionalitร  basate sui vantaggi dell'HTML.

Esistono alcune utili funzionalitร  XML per diversi sistemi e soluzioni:

  • XML รจ estensibile: XML ti consente di creare tag personalizzati per adattarli alla tua applicazione.
  • XML trasporta i dati, non li visualizza: XML consente di memorizzare i dati indipendentemente da come verranno visualizzati.
  • XML รจ uno standard comune: XML รจ stato sviluppato dal World Wide Web Consortium (W3C) ed รจ disponibile come standard aperto.

XML รจ costruito su una struttura di nodi annidati. Ogni nodo ha un tag di apertura e un tag di chiusura come segue:

<node>content</node>

In quale:

  • รจ un tag aperto e il nome di questo tag viene definito da te.
  • รจ un tag di chiusura e il nome di questo tag deve corrispondere al nome del tag di apertura.
  • contenuto รจ il contenuto di questo tag.

All'inizio di ogni file XML รจ necessario dichiarare un tag per indicare la versione XML in uso. La sintassi del tag di istruzione รจ la seguente:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

JSON vs XML: differenze principali

Entrambi i formati contengono dati strutturati e la tabella seguente mostra perchรฉ un progetto potrebbe dover passare da un formato all'altro.

Parametro JSON XML
Stile di sintassi Coppie chiave-valore Tag annidati
Tipi di dati Stringa, numero, booleano, nullo, array, oggetto Solo testo, i tipi provengono da uno schema
Attributi Non supportato Supportato su qualsiasi elemento
Commenti Non supportato Supporto
Verbositร  Terapia Piรน prolisso perchรฉ i tag si ripetono
Validazione dello schema Schema JSON, facoltativo DTD e XSD, maturi
Utilizzo tipico API Web e configurazione Messaggistica e documenti aziendali

Cos'รจ Gson?

Gson (https://github.com/google/gson) รˆ una Java libreria che consente agli utenti di convertire un Java oggetto in una stringa JSON e anche per convertire una stringa JSON di nuovo in un Java oggetto. Gson puรฒ funzionare con arbitrario Java oggetti, inclusi oggetti esistenti di cui non si possiede il codice sorgente.

Dalla versione 1.6, Gson introduce due classi, JsonReader and jSONWriterper fornire l'elaborazione in streaming dei dati JSON.

  • jSONWriter โ€“ Scrittura in streaming su JSON. Creiamo un jSONWriter oggetto. Per iniziare e terminare la creazione di un oggetto JSON, utilizziamo le funzioni inizioOggetto() and fineOggetto()Tra queste due chiamate, scriviamo i dati come coppie (chiave => valore).
JsonWriter writer = new JsonWriter();
writer.beginObject();
writer.name("key").value("value");
writer.endObject();
  • JsonReader โ€“ Lettura in streaming da JSON. Creiamo un oggetto JsonReader. Per iniziare e terminare la lettura di un oggetto JSON, utilizziamo le funzioni beginObject() e endObject(). Tra queste due chiamate, leggiamo i dati come coppie (chiave => valore).
JsonReader reader = new JsonReader();
reader.beginObject();
while (reader.hasNext()) {
	String name = reader.nextName();
	if (name.equals("key")) {
		String value = reader.nextString();
	}
}
reader.endObject();

L'elaborazione in streaming di Gson รจ veloce. Tuttavia, รจ necessario gestire manualmente ogni coppia (chiave => valore) dei dati JSON.

Cos'รจ JAXB?

JAXB sta per Java Architecture per XML Binding, che รจ una libreria che utilizza le annotazioni per la conversione Java oggetti in contenuto XML e viceversa. Poichรฉ JAXB รจ definito da una specifica, possiamo utilizzare diverse implementazioni di questo standard.

Con JAXB, utilizziamo spesso le seguenti annotazioni di base:

  • @XmlRootElement: Questa annotazione specifica il tag piรน esterno del file XML e viene quindi dichiarata sopra una classe.
  • @XmlElementWrapper: questa annotazione crea un elemento XML wrapper attorno alle raccolte.
  • @XmlElement: Questa annotazione dichiara che una proprietร  dell'oggetto diventa un tag figlio del file XML.
  • @XmlAttribute: Questa annotazione dichiara che una proprietร  dell'oggetto diventa un attributo del tag circostante.

L'implementazione generale รจ la seguente. Innanzitutto, inizializziamo il JAXBContesto oggetto con il Il mio oggetto classe da convertire.

JAXBContext jaxbContext = JAXBContext.newInstance(MyObject.class);

Questo JAXBContesto l'oggetto ha un metodo che crea un oggetto che converte il contenuto XML in un Java oggetto, l Disorganizzatore.

Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

Lo stesso JAXBContesto l'oggetto ha anche un metodo che crea l'oggetto che converte un Java oggetto in contenuto XML, il Maresciallo.

Marshaller marshallerObj = jaxbContext.createMarshaller();

โš ๏ธ Attenzione: JAXB รจ stato rimosso dal JDK nel Java 11. Sopra Java 11 e versioni successive, aggiungi esplicitamente l'API e un'implementazione runtime al progetto, ad esempio jakarta.xml.bind:jakarta.xml.bind-api insieme org.glassfish.jaxb:jaxb-runtimee importare le annotazioni da jakarta.xml.bind.annotation invece di javax.xml.bind.annotation.

Come convertire XML in JSON?

Implementiamo l'esempio di conversione da XML a JSON sulla seguente piattaforma. Le versioni riportate di seguito sono quelle utilizzate per gli screenshot. Versioni piรน recenti del JDK, Eclipsee Gson funzionano allo stesso modo, fatte salve le precisazioni relative a JAXB riportate sopra.

  • OpenJDK 8 per Ubuntu 18.04 x64.
  • Eclipse IDE 2019-03 (4.11.0) x64 Java Sviluppo per Ubuntu.
  • Gson 2.8.5.

Passo 1) Crea progetto.
Crea un nuovo Java progetto.

Crea un nuovo Java Progetto.

Passo 2) Imposta il nome del progetto.
Imposta il nome del progetto su XmlToJsonEsempio.

Imposta il nome del progetto

Passo 3) Crea una cartella.
Crea la cartella inserimento dati contenente i due file campione.xml and campione.json.

Crea i dati della cartella

Definiamo innanzitutto il nostro XML con dipartimento, ruoloe persona proprietร .

L'architettura generale รจ la seguente: un dipartimento ha molti ruoli e un ruolo รจ ricoperto da molte persone. Il diagramma seguente illustra queste relazioni.

Relazioni tra oggetti

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
	<department>
		<roles>
			<role id="1">
				<position>head</position>
				<salary>10k</salary>
			</role>
			<role id="2">
				<position>manager</position>
				<salary>8k</salary>
			</role>
			<role id="3">
				<position>employee</position>
				<salary>5k</salary>
			</role>
		</roles>
		<persons>
			<person id="1">
				<name>Red</name>
				<role>1</role>
			</person>
			<person id="2">
				<name>Green</name>
				<role>2</role>
			</person>
			<person id="3">
				<name>Blue</name>
				<role>2</role>
			</person>
			<person id="4">
				<name>Yellow</name>
				<role>3</role>
			</person>
			<person id="5">
				<name>Brown</name>
				<role>3</role>
			</person>
		</persons>
	</department>
</root>

In secondo luogo, definiamo il JSON che esprime la stessa idea. Si noti che l'elenco piatto di persone diventa un array annidato all'interno di ciascun ruolo, che รจ esattamente la trasformazione eseguita dal codice di conversione.

{
	"roles": [
		{
			"id": "1",
			"position": "head",
			"salary": "10k",
			"persons": [
				{
					"id": "1",
					"name": "Red"
				}
			]
		},
		{
			"id": "2",
			"position": "manager",
			"salary": "8k",
			"persons": [
				{
					"id": "2",
					"name": "Green"
				},
				{
					"id": "3",
					"name": "Blue"
				}
			]
		},
		{
			"id": "3",
			"position": "employee",
			"salary": "5k",
			"persons": [
				{
					"id": "4",
					"name": "Yellow"
				},
				{
					"id": "5",
					"name": "Brown"
				}
			]
		}
	]
}

Passo 4) Definire gli oggetti.
Definire le classi di oggetti corrispondenti nel pacchetto modello.

Definire le classi di oggetti

Ruolo.java

@XmlRootElement(name = "role")
public class Role {
	private String id;
	private String position;
	private String salary;
	public Role() {
		super();
	}
	public Role(String id, String position, String salary) {
		super();
		this.id = id;
		this.position = position;
		this.salary = salary;
	}
	@XmlAttribute(name = "id")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@XmlElement(name = "position")
	public String getPosition() {
		return position;
	}
	public void setPosition(String position) {
		this.position = position;
	}
	@XmlElement(name = "salary")
	public String getSalary() {
		return salary;
	}
	public void setSalary(String salary) {
		this.salary = salary;
	}
}

Persona.java

@XmlRootElement(name = "person")
public class Person {
	private String id;
	private String name;
	private String role;
	public Person() {
		super();
	}
	public Person(String id, String name, String role) {
		super();
		this.id = id;
		this.name = name;
		this.role = role;
	}
	@XmlAttribute(name = "id")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@XmlElement(name = "name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	@XmlElement(name = "role")
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
}

Department.java

@XmlRootElement(name = "department")
public class Department {
	private List<Role> roles;
	private List<Person> persons;
	public Department() {
		super();
	}
	public Department(List<Role> roles, List<Person> persons) {
		super();
		this.roles = roles;
		this.persons = persons;
	}
	@XmlElementWrapper(name = "roles")
	@XmlElement(name = "role")
	public List<Role> getRoles() {
		return roles;
	}
	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}
	@XmlElementWrapper(name = "persons")
	@XmlElement(name = "person")
	public List<Person> getPersons() {
		return persons;
	}
	public void setPersons(List<Person> persons) {
		this.persons = persons;
	}
}

XMLModel.java

@XmlRootElement(name = "root")
public class XMLModel {

	private Department department;

	public XMLModel() {
		super();
	}

	public XMLModel(Department department) {
		super();
		this.department = department;
	}

	@XmlElement(name = "department")
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

}

Passo 5) Configura la libreria.
Aggiungi e configura la libreria Gson 2.8.5 nel Java Costruisci percorso.

Configura la libreria Gson

Aggiungi la libreria Gson 2.8.5 in Java Costruisci percorso

Se il progetto utilizza Maven Anzichรฉ aggiungere manualmente un file jar, le stesse librerie vengono dichiarate come dipendenze. La versione 2.8.5 รจ indicata qui per corrispondere agli screenshot, e qualsiasi versione successiva di Gson funziona in modo identico per questo esempio:

<dependencies>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.5</version>
    </dependency>

    <!-- required on Java 11 and later -->
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
    </dependency>
</dependencies>

Converti messaggio XML in Java oggetti che utilizzano JAXB

Innanzitutto, definiamo le classi performanti nel pacchetto INSTALLAZIONE.

Definire le classi di spettacolo

Nella prima fase del primo processo, utilizziamo la tecnica di unmarshalling di JAXB.

La deserializzazione fornisce a un'applicazione client la capacitร  di convertire i dati XML in dati derivati โ€‹โ€‹da JAXB Java oggetti.

Definiamo la funzione getObjectFromXmlFile per deserializzare il nostro file XML in un Java oggetto. Questa funzione รจ definita nella classe XMLService.

public XMLModel getObjectFromXmlFile(String filePath) {
	try {
		File file = new File(filePath);
		JAXBContext jaxbContext = JAXBContext.newInstance(XMLModel.class);

		Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
		XMLModel root = (XMLModel) jaxbUnmarshaller.unmarshal(file);

		return root;
	} catch (JAXBException e) {
		e.printStackTrace();
		return null;
	}
}

Richiamiamo il codice sopra nella classe XmlToJsonService.

XMLService xmlService = new XMLService();
XMLModel xmlModel = xmlService.getObjectFromXmlFile(filePathIn);

Department department = xmlModel.getDepartment();
List<Role> roles = department.getRoles();
List<Person> persons = department.getPersons();

A questo punto il file XML รจ diventato tre Java oggetti in memoria. Il passaggio successivo li scrive in formato JSON.

convertire Java oggetti al messaggio JSON utilizzando Gson

In questa fase definiamo la funzione writeDataToJsonFile per scrivere dati nel file JSON. Questa funzione รจ definita nella classe JsonService.

Nota che per scrivere un elenco di oggetti JSON, utilizziamo le funzioni inizioArray() and endArray()Tra queste due chiamate, scriviamo ciascun oggetto JSON.

public void writeDataToJsonFile(String filePath, List<Role> roles, List<Person> persons) {
	try {
		JsonWriter writer = new JsonWriter(new FileWriter(filePath));
		writer.setIndent("    ");
		writer.beginObject();
		writer.name("roles");
		writer.beginArray();
		for (Role role : roles) {
			writer.beginObject();
			writer.name("id").value(role.getId());
			writer.name("position").value(role.getPosition());
			writer.name("salary").value(role.getSalary());
			writer.name("persons");
			writer.beginArray();
			for (Person person : persons) {
				if (person.getRole().equalsIgnoreCase(role.getId())) {
					writer.beginObject();
					writer.name("id").value(person.getId());
					writer.name("name").value(person.getName());
					writer.endObject();
				}
			}
			writer.endArray();
			writer.endObject();
		}
		writer.endArray();
		writer.endObject();
		writer.close();
	} catch (IOException e) {
	}
}

Richiamiamo il codice sopra nella classe XmlToJsonService.

JsonService jsonService = new JsonService();
jsonService.writeDataToJsonFile(filePathOut, roles, persons);

Questo รจ il primo processo. Il ciclo interno associa ogni persona all'ID del ruolo corrente, ed รจ cosรฌ che l'elenco di persone in formato XML si trasforma in un array JSON annidato.

Converti il โ€‹โ€‹messaggio JSON in Java oggetti che utilizzano Gson

Nella prima fase del secondo processo, definiamo la funzione getDataFromJsonFile per leggere i dati dal file JSON. Questa funzione รจ definita nella classe JsonService.

Nota che per leggere un elenco di oggetti JSON, utilizziamo le funzioni inizioArray() and endArray()Tra queste due chiamate, leggiamo ciascun oggetto JSON.

public void getDataFromJsonFile(String filePath, List<Role> roles, List<Person> persons) {
	try {
		JsonReader reader = new JsonReader(new FileReader(filePath));
		reader.beginObject();
		while (reader.hasNext()) {
			String nameRoot = reader.nextName();
			if (nameRoot.equals("roles")) {
				reader.beginArray();
				while (reader.hasNext()) {
					reader.beginObject();
					Role role = new Role();
					while (reader.hasNext()) {
						String nameRole = reader.nextName();
						if (nameRole.equals("id")) {
							role.setId(reader.nextString());
						} else if (nameRole.equals("position")) {
							role.setPosition(reader.nextString());
						} else if (nameRole.equals("salary")) {
							role.setSalary(reader.nextString());
						} else if (nameRole.equals("persons")) {
							reader.beginArray();
							while (reader.hasNext()) {
								reader.beginObject();

								Person person = new Person();
								person.setRole(role.getId());

								while (reader.hasNext()) {
									String namePerson = reader.nextName();
									if (namePerson.equals("id")) {
										person.setId(reader.nextString());
									} else if (namePerson.equals("name")) {
										person.setName(reader.nextString());
									}
								}
								persons.add(person);
								reader.endObject();
							}
							reader.endArray();
						}
					}
					roles.add(role);
					reader.endObject();
				}
				reader.endArray();
			}
		}
		reader.endObject();
		reader.close();
	} catch (IOException e) {

	}
}

Richiamiamo il codice sopra nella classe XmlToJsonService.

JsonService jsonService = new JsonService();
List<Role> roles = new ArrayList<>();
List<Person> persons = new ArrayList<>();

jsonService.getDataFromJsonFile(filePathIn, roles, persons);

convertire Java oggetti al messaggio XML utilizzando JAXB

In questa fase, utilizziamo la tecnica di marshalling di JAXB.

Il marshalling fornisce a un'applicazione client la capacitร  di convertire un derivato JAXB Java albero degli oggetti in dati XML.

Definiamo la funzione analizzareOggettoInXml per radunare il Java oggetto in un messaggio XML. Questa funzione รจ definita nella classe XMLService.

public void parseObjectToXml(String filePath, XMLModel xmlModel) {
	try {
		JAXBContext contextObj = JAXBContext.newInstance(XMLModel.class);

		Marshaller marshallerObj = contextObj.createMarshaller();
		marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

		marshallerObj.marshal(xmlModel, new FileOutputStream(filePath));
	} catch (JAXBException je) {
		System.out.println("JAXBException");
	} catch (IOException ie) {
		System.out.println("IOException");
	}
}

Richiamiamo il codice sopra nella classe XmlToJsonService.

XMLService xmlService = new XMLService();
XMLModel xmlModel = new XMLModel();

Department department = new Department();
department.setRoles(roles);
department.setPersons(persons);

xmlModel.setDepartment(department);

xmlService.parseObjectToXml(filePathOut, xmlModel);

Questo รจ il secondo processo. Il file generato corrisponde al sample.xml originale, il che conferma che il processo di scambio ha preservato tutti i valori.

Come convertire JSON in XML in Java senza una classe modello?

L'approccio sopra descritto รจ la scelta giusta quando la struttura รจ nota e stabile, perchรฉ le classi annotate documentano la contract. Quando la struttura รจ sconosciuta o cambia spesso, un convertitore generico รจ piรน veloce.

Migliori org.json La libreria esegue la conversione in due righe, senza alcuna classe modello:

import org.json.JSONObject;
import org.json.XML;

public class QuickConverter {

    public static void main(String[] args) {
        String str = "{\"username\":\"guru99user\",\"email\":\"guru99user@mail.com\"}";

        JSONObject json = new JSONObject(str);
        String xml = XML.toString(json);

        System.out.println(xml);
    }
}

Produzione:

<username>guru99user</username><email>guru99user@mail.com</email>

Si noti che il percorso generico non produce alcun elemento radice e nessun attributo, quindi XML.toString(json, "root") รจ normalmente richiesto. La tabella seguente mette a confronto i due approcci.

Criterio Gson con JAXB conversione generica org.json
classi modello richieste Si Non
Controllo sulla struttura Completo, inclusi gli attributi Limitato, solo elementi
Reshaping dati Possibile, come dimostrato con le persone annidate Non possibile
Linee di codice Molti Due
migliori per Schemi stabili e documentati Strutture ad hoc o sconosciute

JAXB legge i dati XML e Gson li scrive in JSON, e il percorso inverso utilizza Gson per leggere JSON dati mentre JAXB li riscrive in XML. Per approfondire, rivedere XML fondamenti, il piรน ampio Java lezionee Jasper Reports, che utilizza entrambi i formati come fonti di dati per i report.

DOMANDE FREQUENTI

JAXB รจ stato rimosso dal JDK nel Java 11. Aggiungere l'API jakarta.xml.bind insieme a un runtime come jaxb-runtime e aggiornare le importazioni da javax a jakarta.

No. Gson gestisce solo JSON. L'XML deve prima diventare Java oggetti tramite JAXB, o tramite un altro parser come Jackson XML, prima che Gson possa serializzarli.

XmlElement crea un tag figlio contenente il valore, mentre XmlAttribute inserisce il valore all'interno del tag di apertura del tag padre. Gli attributi non possono contenere strutture annidate.

Lo streaming mantiene basso il consumo di memoria e consente alla struttura di output di differire dalle classi di input, che รจ esattamente ciรฒ che accade quando le persone sono annidate all'interno dei ruoli in questo caso.

Sรฌ, da un documento XML di esempio. Verifica le annotazioni wrapper sulle collezioni, perchรฉ le classi generate spesso omettono XmlElementWrapper e producono una struttura appiattita.

JSON e la sua variante con delimitatori di riga dominano, perchรฉ si mappano direttamente su Python dizionari e streaming efficienti. L'XML รจ ancora presente laddove i sistemi aziendali legacy forniscono i dati di origine.

Riassumi questo post con: