Převést JSON na XML Java pomocí Gsonu a JAXB

⚡ Chytré shrnutí

Převést JSON na XML Java pomocí Gson a JAXB pomocí mapyping oba formáty na stejný anotovaný Java třídy. Tento článek definuje jednotlivé formáty, nastavuje projekt, demaršuje XML pomocí JAXB, zapisuje JSON pomocí Gson a celý proces opakuje.

  • 🗝️ Struktura JSON: Data jsou uložena jako páry klíč-hodnota uvnitř složených závorek, přičemž jednotlivé položky jsou odděleny čárkami.
  • ???? ️ Struktura XML: Data jsou uložena ve vnořených uzlech, kde každý otevírací tag vyžaduje odpovídající uzavírací tag.
  • 🔗 Sdílený model: Jedna sada anotovaných Java třídy fungují jako most, takže žádný formát není přímo analyzován do druhého.
  • 📥 Odstraňování seřazení: JAXB čte XML soubor a vrací vyplněný Java strom objektů prostřednictvím třídy Unmarshaller.
  • 📤 Streamování zápisu: Gson JsonWriter generuje JSON inkrementálně s voláním beginObject, name, value a endObject.
  • 🔄 Reverse Cesta: JsonReader znovu sestaví objekty z JSON a JAXB Marshaller je zapíše zpět jako XML.
  • ⚠️ Poznámka za běhu: JAXB opustil JDK v Java 11, takže závislost jakarta.xml.bind musí být explicitně přidána.

Převést JSON do XML v Java

Co je JSON?

JSON je zkratka pro JavaNotace objektů skriptu, což je datový formát, který se řídí pravidly, která většina programovacích jazyků umí číst. Můžeme jej snadno uložit do souboru nebo do databáze. Formát JSON používá k popisu dat páry klíč-hodnota.

V následujícím příkladu definujeme řetězec JSON, který ukládá osobní údaje:

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

Syntaxe JSON je tedy velmi jednoduchá. Každá datová položka má dvě části, klíč a hodnotu, které odpovídají názvu pole a jeho hodnotě v záznamu. Při dalším pohledu existuje několik pravidel, jako je toto:

  • Řetězec JSON je uzavřen do složených závorek {}.
  • Klíče JSON musí být uzavřeny v uvozovkách a řetězcové hodnoty musí být také v uvozovkách.
  • Pokud je dat více (více párů klíč => hodnota), oddělujeme je čárkami (,).
  • Klíče JSON by měly používat obyčejná písmena, číslice nebo podtržítko bez mezer a první znak by neměl být číslo.

Co je XML?

XML je zkratka pro eXtensible Markup Language (eXtensible Markup Language), navržená konsorciem World Wide Web (WWC).https://www.w3.org/) k vytváření dalších značkovacích jazyků. Jedná se o jednoduchou podmnožinu, která dokáže popsat mnoho různých typů dat, takže je velmi užitečná pro sdílení dat mezi systémy.

Tagy v XML často nejsou předdefinované, ale jsou vytvářeny podle uživatelských konvencí. XML zavádí nové funkce založené na výhodách HTML.

Pro různé systémy a řešení existuje několik užitečných funkcí XML:

  • XML je rozšiřitelné: XML vám umožňuje vytvářet vlastní vlastní značky, které vyhovují vaší aplikaci.
  • XML data přenáší, nezobrazuje je: XML umožňuje ukládat data bez ohledu na to, jak budou zobrazena.
  • XML je běžný standard: XML byl vyvinut konsorciem World Wide Web Consortium (W3C) a je k dispozici jako otevřený standard.

XML je postaven na vnořené struktuře uzlů. Každý uzel má otevírací a uzavírací tag takto:

<node>content</node>

Ve kterém:

  • je otevřený tag a název tohoto tagu definujete vy.
  • je uzavírací tag a název tohoto tagu se musí shodovat s názvem otevíracího tagu.
  • obsah je obsahem tohoto tagu.

V horní části každého XML souboru je nutné deklarovat tag označující používanou verzi XML. Syntaxe tagu instrukce:

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

JSON vs. XML: Klíčové rozdíly

Oba formáty obsahují strukturovaná data a tabulka níže ukazuje, proč může být v rámci projektu nutné mezi nimi přecházet.

Parametr JSON XML
Syntaktický styl Páry klíč a hodnota Vnořené tagy
Typy dat Řetězec, číslo, booleovská hodnota, null, pole, objekt Pouze text, typy pocházejí ze schématu
Atributy Není podporováno Podporováno na jakémkoli prvku
Komentáře Není podporováno Podporované
Výřečnost Kompaktní Podrobnější, protože se tagy opakují
Validace schématu Schéma JSON, volitelné DTD a XSD, zralé
Typické použití Webová API a konfigurace Podnikové zprávy a dokumenty

Co je Gson?

Gson (https://github.com/google/gson) Je Java knihovna, která umožňuje uživatelům konvertovat Java objekt na řetězec JSON a také převést řetězec JSON zpět na Java objekt. Gson může pracovat s libovolným Java objekty, včetně existujících objektů, jejichž zdrojový kód nemáte.

Od verze 1.6 Gson zavádí dvě třídy, JsonReader a JsonWriter, aby bylo možné streamovat data JSON.

  • JsonWriter – Streamování zápisu do JSON. Vytvoříme JsonWriter objekt. Pro zahájení a dokončení vytváření objektu JSON používáme funkce beginObject() a endObject()Mezi těmito dvěma voláními zapisujeme data jako páry (klíč => hodnota).
JsonWriter writer = new JsonWriter();
writer.beginObject();
writer.name("key").value("value");
writer.endObject();
  • JsonReader – Streamování čtení z JSON. Vytvoříme objekt JsonReader. Pro zahájení a ukončení čtení objektu JSON použijeme funkce beginObject() a endObject(). Mezi těmito dvěma voláními čteme data jako páry (klíč => hodnota).
JsonReader reader = new JsonReader();
reader.beginObject();
while (reader.hasNext()) {
	String name = reader.nextName();
	if (name.equals("key")) {
		String value = reader.nextString();
	}
}
reader.endObject();

Zpracování streamování Gson je rychlé. Každý pár (klíč => hodnota) dat JSON si však musíte zpracovat sami.

Co je JAXB?

Zkratka JAXB znamená Java Architecture for XML Binding, což je knihovna, která ke konverzi používá anotace Java objekty do XML obsahu a naopak. Protože JAXB je definován specifikací, můžeme použít různé implementace tohoto standardu.

V JAXB často používáme následující základní anotace:

  • @XmlRootElementTato anotace určuje nejvzdálenější tag XML souboru, a proto je deklarována nad třídou.
  • @XmlElementWrapper: Tato anotace vytvoří kolem kolekcí obalový prvek XML.
  • @XmlElementTato anotace deklaruje, že vlastnost objektu se stane podřízenou značkou souboru XML.
  • @XmlAttributeTato anotace deklaruje, že vlastnost objektu se stává atributem okolního tagu.

Obecná implementace je následující. Nejprve inicializujeme JAXBContext objekt s MůjObjekt třída k převodu.

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

Toto JAXBContext objekt má metodu, která vytváří objekt, jenž převádí obsah XML do Java objekt, ten Unmarshaller.

Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

Stejný JAXBContext Objekt má také metodu, která vytváří objekt, který převádí Java objekt do obsahu XML, Marshaller.

Marshaller marshallerObj = jaxbContext.createMarshaller();

Warning️ Varování: JAXB byl z JDK odstraněn v roce Java 11. Na Java 11 a novější, přidejte API a implementaci běhového prostředí do projektu explicitně, například jakarta.xml.bind:jakarta.xml.bind-api Spolu s org.glassfish.jaxb:jaxb-runtimea importujte anotace z jakarta.xml.bind.annotation místo javax.xml.bind.annotation.

Jak převést XML na JSON?

Příklad převodu XML do JSON implementujeme na následující platformě. Níže uvedené verze jsou ty, které byly použity pro snímky obrazovky. Novější verze JDK, Eclipsea Gson fungují stejným způsobem, s výhradou výše uvedené poznámky JAXB.

  • OpenJDK 8 pro Ubuntu 18.04 x64.
  • Eclipse IDE 2019-03 (4.11.0) x64 Java Vývoj pro Ubuntu.
  • Gson 2.8.5.

Krok 1) Vytvořit projekt.
Vytvoř nový Java projekt.

Vytvoř nový Java Projekt.

Krok 2) Nastavte název projektu.
Nastavte název projektu na XmlToJsonExample.

Nastavit název projektu

Krok 3) Vytvořte složku.
Vytvořte složku data/vstup obsahující dva soubory ukázka.xml a sample.json.

Vytvořte data složky

Nejprve definujme náš XML pomocí oddělení, role, a člověk Vlastnosti.

Obecná architektura je následující: jedno oddělení má mnoho rolí a jedna role má mnoho osob. Níže uvedený diagram znázorňuje tyto vztahy.

Objektové vztahy

<?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>

Za druhé definujeme JSON, který vyjadřuje stejnou myšlenku. Všimněte si, že seznam osob se stává vnořeným polem uvnitř každé role, což je přesně ta transformace, kterou provádí konverzní kód.

{
	"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"
				}
			]
		}
	]
}

Krok 4) Definujte objekty.
Definujte odpovídající třídy objektů v balíčku model.

Definujte třídy objektů

Role.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;
	}
}

Person.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;
	}

}

Krok 5) Zařiďte knihovnu.
Přidejte a nastavte knihovnu Gson 2.8.5 v Java Vytvořit cestu.

Nastavte knihovnu Gson

Přidejte do knihovny Gson 2.8.5 Java Vytvořit cestu

Pokud projekt využívá Maven Místo ručně přidaného souboru JAR jsou stejné knihovny deklarovány jako závislosti. Verze 2.8.5 je zde připnuta, aby odpovídala snímkům obrazovky, a jakákoli pozdější verze Gsonu funguje pro tento příklad identicky:

<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>

Převést zprávu XML na Java objektů pomocí JAXB

Nejprve definujeme výkonné třídy v balíčku. servis.

Definujte třídy výkonu

V prvním kroku prvního procesu používáme techniku ​​un-marshallingu JAXB.

Odstranění marshallingu poskytuje klientské aplikaci možnost převést XML data do formátu odvozeného z JAXB. Java objekty.

Definujeme funkci getObjectFromXmlFile k opětovnému zařazení našeho XML souboru do Java objekt. Tato funkce je definována ve třídě 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;
	}
}

Voláme výše uvedený kód ve třídě XmlToJsonService.

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

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

V tomto okamžiku se XML soubor rozdělil na tři Java objekty v paměti. V dalším kroku je zapíšeme jako JSON.

Konvertovat Java objektů do zprávy JSON pomocí Gson

V tomto kroku definujeme funkci writeDataToJsonFile pro zápis dat do souboru JSON. Tato funkce je definována ve třídě JsonService.

Všimněte si, že k zápisu seznamu objektů JSON používáme funkce beginArray() a endArray()Mezi těmito dvěma voláními zapíšeme každý objekt 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) {
	}
}

Výše uvedený kód voláme ve třídě XmlToJsonService.

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

To je první proces. Vnitřní smyčka porovnává každou osobu s aktuálním ID role, čímž se z plochého seznamu osob v XML stane vnořené pole JSON.

Převést zprávu JSON na Java objektů pomocí Gson

V prvním kroku druhého procesu definujeme funkci getDataFromJsonFile pro čtení dat ze souboru JSON. Tato funkce je definována ve třídě JsonService.

Všimněte si, že pro čtení seznamu objektů JSON používáme funkce beginArray() a endArray()Mezi těmito dvěma voláními načteme každý objekt 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) {

	}
}

Výše uvedený kód voláme ve třídě XmlToJsonService.

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

jsonService.getDataFromJsonFile(filePathIn, roles, persons);

Konvertovat Java objektů do zprávy XML pomocí JAXB

V tomto kroku používáme techniku ​​marshallingu JAXB.

Marshalling poskytuje klientské aplikaci možnost převést soubor odvozený z JAXB Java objektový strom do XML dat.

Definujeme funkci parsovatObjectToXml usměrnit Java objekt pro XML zprávu. Tato funkce je definována ve třídě 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");
	}
}

Výše uvedený kód voláme ve třídě 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);

To je druhý proces. Vygenerovaný soubor odpovídá původnímu souboru sample.xml, což potvrzuje, že při oboustranném přenosu byly zachovány všechny hodnoty.

Jak převést JSON do XML v Java bez modelové třídy?

Výše uvedený přístup je správnou volbou, pokud je struktura známá a stabilní, protože anotované třídy dokumentují contract. Pokud je struktura neznámá nebo se často mění, je generický převodník rychlejší.

Jedno org.json Knihovna provede konverzi ve dvou řádcích, bez jakékoli modelové třídy:

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);
    }
}

Výstup:

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

Všimněte si, že generická trasa neprodukuje žádný kořenový element ani žádné atributy, takže XML.toString(json, "root") je obvykle vyžadováno. Níže uvedená tabulka uvádí oba přístupy vedle sebe.

Kritérium Gson s JAXB Generická konverze org.json
Požadované modelové třídy Ano Ne
Kontrola nad strukturou Plné, včetně atributů Omezené, pouze prvky
Rešaping datum Možné, jak je znázorněno u vnořených osob Není to možné
Řádky kódu Mnoho Dvě
Nejlepší pro Stabilní, dokumentovaná schémata Ad hoc nebo neznámé struktury

JAXB čte XML data a Gson je zapisuje do JSON a zpětná cesta používá Gson ke čtení. JSON data, zatímco JAXB je zapisuje zpět do XML. Chcete-li jít dále, podívejte se XML základy, širší Java konzultace, a Jasper Zprávy, který využívá oba formáty jako zdroje dat pro sestavy.

Nejčastější dotazy

JAXB byl z JDK odstraněn v roce Java 11. Přidejte API jakarta.xml.bind spolu s běhovým prostředím, jako je například jaxb-runtime, a aktualizujte importy z javax do jakarta.

Ne. Gson zpracovává pouze JSON. XML se musí nejdříve stát… Java objekty přes JAXB nebo přes jiný parser, jako je Jackson XML, než je Gson může serializovat.

XmlElement vytvoří podřízený tag obsahující hodnotu, zatímco XmlAttribute umístí hodnotu dovnitř otevíracího tagu nadřazeného prvku. Atributy nemohou obsahovat vnořené struktury.

Streamování snižuje využití paměti a umožňuje, aby se výstupní struktura lišila od vstupních tříd, což se přesně stává, když jsou osoby vnořeny uvnitř rolí.

Ano, z ukázkového dokumentu XML. Ověřte anotace obalů u kolekcí, protože generované třídy často vynechávají XmlElementWrapper a vytvářejí zploštělou strukturu.

JSON a jeho varianta s oddělenými řádky dominují, protože se mapují přímo na Python slovníky a efektivně streamovat. XML se stále objevuje tam, kde zdrojová data dodávají starší podnikové systémy.

Shrňte tento příspěvek takto: