Konwertuj JSON na XML Java używając Gson i JAXB
⚡ Inteligentne podsumowanie
Konwertuj JSON na XML Java używając Gson i JAXB według mapyping oba formaty na tym samym adnotowanym Java Klasy. W tym artykule zdefiniujemy każdy format, skonfigurujemy projekt, rozpakujemy XML za pomocą JAXB, zapiszemy JSON za pomocą Gson i odwrócimy cały proces.
Co to jest JSON?
JSON to skrót od JavaNotacja obiektów skryptowych (Script Object Notation), czyli format danych zgodny z regułami, które można odczytać w większości języków programowania. Można go łatwo zapisać do pliku lub przechowywać w bazie danych. Format JSON wykorzystuje pary klucz-wartość do opisu danych.
W poniższym przykładzie definiujemy ciąg JSON przechowujący dane osobowe:
{
"username" : "guru99user",
"email" : "guru99user@mail.com"
}
Składnia JSON jest więc bardzo prosta. Każdy element danych składa się z dwóch części: klucza i wartości, które odpowiadają nazwie pola i jego wartości w rekordzie. Patrząc dalej, istnieje kilka reguł, takich jak ta:
- Ciąg JSON jest ujęty w nawiasy klamrowe {}.
- Klucze JSON muszą być ujęte w podwójne cudzysłowy, a wartości ciągów również muszą być ujęte w cudzysłowy.
- Jeśli danych jest więcej (więcej par klucz => wartość), używamy przecinków (,), aby je rozdzielić.
- Klucze JSON powinny zawierać zwykłe litery, cyfry lub znak podkreślenia, bez spacji, a pierwszy znak nie powinien być cyfrą.
Co to jest XML?
XML to skrót od eXtensible Markup Language, zaproponowanego przez World Wide Web Consortium (https://www.w3.org/) do tworzenia innych języków znaczników. To prosty podzbiór, który może opisywać wiele różnych typów danych, dlatego jest bardzo przydatny do udostępniania danych między systemami.
Tagi w formacie XML często nie są predefiniowane, ale tworzone są zgodnie z konwencjami użytkownika. XML wprowadza nowe funkcje oparte na zaletach HTML.
Istnieje kilka przydatnych funkcji XML dla różnych systemów i rozwiązań:
- XML jest rozszerzalny: XML umożliwia tworzenie własnych, niestandardowych tagów pasujących do Twojej aplikacji.
- XML służy do przechowywania danych, a nie do ich wyświetlania: XML pozwala na przechowywanie danych niezależnie od sposobu ich wyświetlania.
- XML jest powszechnym standardem: XML został opracowany przez konsorcjum World Wide Web Consortium (W3C) i jest dostępny jako otwarty standard.
XML opiera się na zagnieżdżonej strukturze węzłów. Każdy węzeł ma znacznik otwierający i zamykający, jak pokazano poniżej:
<node>content</node>
W którym:
- jest otwartym tagiem, a nazwa tego tagu jest definiowana przez Ciebie.
- jest tagiem zamykającym, a nazwa tego tagu musi być taka sama, jak nazwa tagu otwierającego.
- zawartość jest zawartością tego tagu.
Na górze każdego pliku XML należy zadeklarować znacznik wskazujący używaną wersję XML. Składnia znacznika instrukcji:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
JSON kontra XML: kluczowe różnice
Oba formaty zawierają ustrukturyzowane dane. Poniższa tabela pokazuje, dlaczego w projekcie może zaistnieć potrzeba przeniesienia się między nimi.
| Parametr | JSON | XML |
|---|---|---|
| Styl składni | Pary klucz-wartość | Zagnieżdżone znaczniki |
| Typy danych | Ciąg, liczba, wartość logiczna, null, tablica, obiekt | Tylko tekst, typy pochodzą ze schematu |
| Atrybuty | Nie jest obsługiwany | Obsługiwane na dowolnym elemencie |
| Komentarze | Nie jest obsługiwany | Utrzymany |
| Gadatliwość | Kompaktowy | Bardziej szczegółowe, ponieważ tagi się powtarzają |
| Walidacja schematu | Schemat JSON, opcjonalny | DTD i XSD, dojrzałe |
| Typowe zastosowanie | Interfejsy API sieci Web i konfiguracja | Wiadomości i dokumenty korporacyjne |
Co to jest Gson?
Gson (https://github.com/google/gson) Stanowi Java biblioteka umożliwiająca użytkownikom konwersję Java obiekt do ciągu JSON, a także do konwersji ciągu JSON z powrotem na Java obiekt. Gson może pracować z dowolnym Java obiekty, w tym istniejące obiekty, których kodu źródłowego nie posiadasz.
Od wersji 1.6 Gson wprowadza dwie klasy, JsonReader oraz JsonWriter, aby zapewnić strumieniowe przetwarzanie danych JSON.
- JsonWriter – Zapis strumieniowy do JSON. Tworzymy JsonWriter obiekt. Aby rozpocząć i zakończyć tworzenie obiektu JSON, używamy funkcji rozpocząćObiekt() oraz obiekt końcowy(). Pomiędzy tymi dwoma wywołaniami zapisujemy dane jako pary (klucz => wartość).
JsonWriter writer = new JsonWriter();
writer.beginObject();
writer.name("key").value("value");
writer.endObject();
- JsonReader – Odczyt strumieniowy z JSON. Tworzymy obiekt JsonReader. Aby rozpocząć i zakończyć odczyt obiektu JSON, używamy funkcji beginObject() i endObject(). Pomiędzy tymi dwoma wywołaniami odczytujemy dane parami (klucz => wartość).
JsonReader reader = new JsonReader();
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("key")) {
String value = reader.nextString();
}
}
reader.endObject();
Przetwarzanie strumieniowe GSON jest szybkie. Musisz jednak samodzielnie obsłużyć każdą parę (klucz => wartość) danych JSON.
Co to jest JAXB?
JAXB oznacza Java Architecture for XML Binding, która jest biblioteką korzystającą z adnotacji do konwersji Java obiekty do treści XML i odwrotnie. Ponieważ JAXB jest zdefiniowany w specyfikacji, możemy używać różnych implementacji tego standardu.
W przypadku JAXB często stosujemy następujące podstawowe adnotacje:
- @XmlRootElement:Ta adnotacja określa najbardziej zewnętrzny znacznik pliku XML i dlatego jest deklarowana powyżej klasy.
- @XmlElementWrapper: Ta adnotacja tworzy element XML opakowania wokół kolekcji.
- @XmlElement:Ta adnotacja deklaruje, że właściwość obiektu staje się tagiem podrzędnym pliku XML.
- @XmlAttribute:Ta adnotacja deklaruje, że właściwość obiektu staje się atrybutem otaczającego znacznika.
Ogólna implementacja wygląda następująco. Najpierw inicjujemy JAXBKontekst obiekt z MójObiekt klasa do konwersji.
JAXBContext jaxbContext = JAXBContext.newInstance(MyObject.class);
Ten JAXBKontekst obiekt ma metodę, która tworzy obiekt konwertujący zawartość XML na Java obiekt, ten Niemarshaller.
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
To samo JAXBKontekst Obiekt ma również metodę, która tworzy obiekt, który konwertuje Java obiekt do zawartości XML, Marshall.
Marshaller marshallerObj = jaxbContext.createMarshaller();
⚠️ Ostrzeżenie: JAXB został usunięty z JDK w Java 11. Na Java W wersji 11 i nowszych należy jawnie dodać do projektu interfejs API i implementację środowiska wykonawczego, na przykład jakarta.xml.bind:jakarta.xml.bind-api Wraz z org.glassfish.jaxb:jaxb-runtimei zaimportuj adnotacje z jakarta.xml.bind.annotation zamiast javax.xml.bind.annotation.
Jak przekonwertować XML na JSON?
Implementujemy przykład konwersji XML do JSON na poniższej platformie. Poniższe wersje są tymi, które wykorzystano do zrzutów ekranu. Nowsze wersje JDK, Eclipsei Gson działają w ten sam sposób, z zastrzeżeniem powyższej notatki JAXB.
- OpenJDK 8 dla Ubuntu 18.04 x64.
- Eclipse IDE 2019-03 (4.11.0) x64 Java Rozwój dla Ubuntu.
- Gson 2.8.5.
Krok 1) Utwórz projekt.
Stwórz nowy Java projekt.
Krok 2) Ustaw nazwę projektu.
Ustaw nazwę projektu na Przykład XmlToJson.
Krok 3) Utwórz folder.
Utwórz folder wprowadzanie danych zawierający dwa pliki próbka.xml oraz próbka.json.
Najpierw zdefiniujmy nasz XML za pomocą dział, rola, osoba Właściwości.
Ogólna architektura wygląda następująco: jeden dział ma wiele ról, a jedna rola ma wiele osób. Poniższy diagram przedstawia te zależności.
<?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>
Po drugie, definiujemy kod JSON, który wyraża tę samą ideę. Zauważ, że płaska lista osób staje się zagnieżdżoną tablicą wewnątrz każdej roli, co jest dokładnie tą samą transformacją, którą wykonuje kod konwersji.
{
"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) Zdefiniuj obiekty.
Zdefiniuj odpowiednie klasy obiektów w pakiecie model.
Rola.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; } }
Osoba.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; } }
Dział.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) Skonfiguruj bibliotekę.
Dodaj i skonfiguruj bibliotekę Gson 2.8.5 w Java Buduj ścieżkę.
Jeśli projekt wykorzystuje Maven Zamiast ręcznie dodawanego pliku jar, te same biblioteki są deklarowane jako zależności. Wersja 2.8.5 jest tutaj przypięta, aby pasowała do zrzutów ekranu, a każda późniejsza wersja Gson działa identycznie w tym przykładzie:
<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>
Konwertuj wiadomość XML na Java obiekty przy użyciu JAXB
Najpierw definiujemy klasy wykonawcze w pakiecie usługa.
Na pierwszym etapie pierwszego procesu wykorzystujemy technikę unmarshallingu JAXB.
Rozdzielanie zapewnia aplikacji klienckiej możliwość konwersji danych XML na dane pochodzące z JAXB Java obiekty.
Definiujemy funkcję getObjectFromXmlFile aby z powrotem przekształcić nasz plik XML w Java obiekt. Ta funkcja jest zdefiniowana w klasie Usługa XML.
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; } }
Powyższy kod wywołujemy w klasie Usługa XmlToJson.
XMLService xmlService = new XMLService(); XMLModel xmlModel = xmlService.getObjectFromXmlFile(filePathIn); Department department = xmlModel.getDepartment(); List<Role> roles = department.getRoles(); List<Person> persons = department.getPersons();
W tym momencie plik XML stał się trzyczęściowy Java obiekty w pamięci. Następny krok zapisuje je w formacie JSON.
konwertować Java obiekty do wiadomości JSON przy użyciu Gsona
Na tym etapie definiujemy funkcję napiszDataToJsonFile do zapisu danych do pliku JSON. Ta funkcja jest zdefiniowana w klasie Usługa Json.
Należy pamiętać, że aby zapisać listę obiektów JSON, używamy funkcji początekArray() oraz tablica końcowa()Pomiędzy tymi dwoma wywołaniami zapisujemy każdy obiekt 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) { } }
Powyższy kod wywołujemy w klasie Usługa XmlToJson.
JsonService jsonService = new JsonService(); jsonService.writeDataToJsonFile(filePathOut, roles, persons);
To jest pierwszy proces. Pętla wewnętrzna dopasowuje każdą osobę do bieżącego identyfikatora roli, w ten sposób płaska lista osób XML staje się zagnieżdżoną tablicą JSON.
Konwertuj wiadomość JSON na Java obiektów za pomocą Gsona
W pierwszym kroku drugiego procesu definiujemy funkcję pobierz dane z pliku Json do odczytu danych z pliku JSON. Ta funkcja jest zdefiniowana w klasie Usługa Json.
Należy pamiętać, że aby odczytać listę obiektów JSON, używamy funkcji początekArray() oraz tablica końcowa()Pomiędzy tymi dwoma wywołaniami odczytujemy każdy obiekt 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) { } }
Powyższy kod wywołujemy w klasie Usługa XmlToJson.
JsonService jsonService = new JsonService(); List<Role> roles = new ArrayList<>(); List<Person> persons = new ArrayList<>(); jsonService.getDataFromJsonFile(filePathIn, roles, persons);
konwertować Java obiektów do wiadomości XML przy użyciu JAXB
Na tym etapie wykorzystujemy technikę marszałkowską JAXB.
Marshalling zapewnia aplikacji klienckiej możliwość konwersji danych pochodzących z JAXB Java drzewo obiektów na dane XML.
Definiujemy funkcję parseObjectToXml zgromadzić Java obiekt do wiadomości XML. Ta funkcja jest zdefiniowana w klasie Usługa XML.
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"); } }
Powyższy kod wywołujemy w klasie Usługa XmlToJson.
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 jest drugi proces. Wygenerowany plik jest zgodny z oryginalnym plikiem sample.xml, co potwierdza, że w obie strony wszystkie wartości zostały zachowane.
Jak przekonwertować JSON na XML w Java bez klasy modelu?
Powyższe podejście jest właściwym wyborem, gdy struktura jest znana i stabilna, ponieważ adnotowane klasy dokumentujątract. Jeśli struktura jest nieznana lub często się zmienia, szybszym rozwiązaniem jest konwerter ogólny.
org.json Biblioteka wykonuje konwersję w dwóch wierszach, bez żadnej klasy modelu:
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); } }
Wyjście:
<username>guru99user</username><email>guru99user@mail.com</email>
Należy pamiętać, że trasa ogólna nie generuje żadnego elementu głównego ani żadnych atrybutów, więc XML.toString(json, "root") jest zazwyczaj wymagane. Poniższa tabela zestawia oba podejścia.
| Kryterium | Gson z JAXB | konwersja ogólna org.json |
|---|---|---|
| Wymagane klasy modeli | Tak | Nie |
| Kontrola nad strukturą | Pełny, w tym atrybuty | Ograniczone, tylko elementy |
| Reszaping dane | Możliwe, jak pokazano na przykładzie zagnieżdżonych osób | Niemożliwe |
| Linie kodu | Wiele | dwa |
| Najlepszy dla | Stabilne, udokumentowane schematy | Struktury ad hoc lub nieznane |
JAXB odczytuje dane XML, a Gson zapisuje je do JSON, a ścieżka odwrotna używa Gson do odczytu JSON dane, podczas gdy JAXB zapisuje je z powrotem do XML. Aby dowiedzieć się więcej, zapoznaj się z XML podstawy, szersze Java Tutorial, JasperRaporty, który wykorzystuje oba formaty jako źródła danych raportów.









