Serialisasi XML dan Deserialisasi dengan Jackson

1. Ikhtisar

Dalam tutorial ini, kita akan melihat bagaimana membuat serial objek Java ke data XML menggunakan Jackson 2.x dan deserialisasinya kembali ke POJO .

Kami akan fokus pada operasi dasar yang tidak memerlukan banyak kerumitan atau penyesuaian.

2. Objek XmlMapper

XmlMapper adalah kelas utama dari Jackson 2.x yang membantu kita dalam serialisasi, jadi kita perlu membuat contohnya:

XmlMapper mapper = new XmlMapper();

Ini mapper tersedia di jackson-dataformat-xml jar, jadi kita harus menambahkannya sebagai ketergantungan untuk kami pom.xml :

 com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.11.1 

Harap periksa versi terbaru dependensi jackson-dataformat-xml di repositori Maven.

3. Menyerialkan Java ke XML

XmlMapper adalah subclass dari ObjectMapper yang digunakan dalam serialisasi JSON. Namun, itu menambahkan beberapa tweak khusus XML ke kelas induk.

Sekarang kita dapat melihat bagaimana menggunakannya untuk melakukan serialisasi yang sebenarnya. Mari buat kelas Java dulu:

class SimpleBean { private int x = 1; private int y = 2; //standard setters and getters }

3.1. Serialisasi ke String XML

Kita bisa membuat serial objek Java kita ke XML String :

@Test public void whenJavaSerializedToXmlStr_thenCorrect() throws JsonProcessingException { XmlMapper xmlMapper = new XmlMapper(); String xml = xmlMapper.writeValueAsString(new SimpleBean()); assertNotNull(xml); }

Hasilnya kita akan mendapatkan:

 1 2 

3.2. Serialisasi ke File XML

Kami juga dapat membuat serial objek Java kami ke file XML:

@Test public void whenJavaSerializedToXmlFile_thenCorrect() throws IOException { XmlMapper xmlMapper = new XmlMapper(); xmlMapper.writeValue(new File("simple_bean.xml"), new SimpleBean()); File file = new File("simple_bean.xml"); assertNotNull(file); }

Dan di bawah ini kita bisa melihat konten dari file yang dihasilkan bernama simple_bean.xml :

 1 2 

4. Deserialisasi XML ke Java

Di bagian ini, kita akan melihat cara mendapatkan objek Java dari XML.

4.1. Deserialisasi Dari String XML

Seperti serialisasi, kita juga dapat melakukan deserialisasi XML String kembali ke objek Java:

@Test public void whenJavaGotFromXmlStr_thenCorrect() throws IOException { XmlMapper xmlMapper = new XmlMapper(); SimpleBean value = xmlMapper.readValue("12", SimpleBean.class); assertTrue(value.getX() == 1 && value.getY() == 2); }

4.2. Deserialisasi Dari File XML

Demikian juga, jika kita memiliki file XML, kita dapat mengubahnya kembali menjadi objek Java.

Di sini, pertama kita membaca file tersebut menjadi aliran input dan kemudian mengubah aliran input menjadi String dengan metode utilitas sederhana.

Sisa kode serupa dengan yang ada di bagian 4.1:

@Test public void whenJavaGotFromXmlFile_thenCorrect() throws IOException { File file = new File("simple_bean.xml"); XmlMapper xmlMapper = new XmlMapper(); String xml = inputStreamToString(new FileInputStream(file)); SimpleBean value = xmlMapper.readValue(xml, SimpleBean.class); assertTrue(value.getX() == 1 && value.getY() == 2); }

Metode utilitas:

public String inputStreamToString(InputStream is) throws IOException { StringBuilder sb = new StringBuilder(); String line; BufferedReader br = new BufferedReader(new InputStreamReader(is)); while ((line = br.readLine()) != null) { sb.append(line); } br.close(); return sb.toString(); }

5. Menangani Elemen Kapitalisasi

Di bagian ini, kita akan melihat bagaimana menangani skenario di mana kita memiliki XML dengan elemen yang dikapitalisasi untuk deserialisasi atau kita perlu membuat serial objek Java ke XML dengan satu atau lebih elemen yang dikapitalisasi.

5.1. Deserialisasi Dari String XML

Katakanlah kita memiliki XML dengan satu bidang yang dikapitalisasi:

 1 2 

Untuk menangani elemen yang dikapitalisasi dengan benar, kita perlu menganotasi bidang "x" dengan anotasi @JsonProperty :

class SimpleBeanForCapitalizedFields { @JsonProperty("X") private int x = 1; private int y = 2; // standard getters, setters }

Sekarang kita dapat dengan benar melakukan deserialisasi XML String kembali ke objek Java:

@Test public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException { XmlMapper xmlMapper = new XmlMapper(); SimpleBeanForCapitalizedFields value = xmlMapper.readValue( "12", SimpleBeanForCapitalizedFields.class); assertTrue(value.getX() == 1 && value.getY() == 2); }

5.2. Serialisasi ke String XML

Dengan memberi anotasi bidang wajib dengan @JsonProperty, kita dapat membuat serial objek Java dengan benar menjadi String XML dengan satu atau beberapa elemen yang dikapitalisasi:

@Test public void whenJavaSerializedToXmlFileWithCapitalizedField_thenCorrect() throws IOException { XmlMapper xmlMapper = new XmlMapper(); xmlMapper.writeValue(new File("target/simple_bean_capitalized.xml"), new SimpleBeanForCapitalizedFields()); File file = new File("target/simple_bean_capitalized.xml"); assertNotNull(file); }

6. Daftar Serial ke XML

The XmlMapper mampu cerita bersambung seluruh kacang Java ke dalam dokumen. Untuk mengonversi objek Java ke XML, kita akan mengambil contoh sederhana dengan objek dan array bersarang.

Our intent is to serialize a Person object, along with its composed Address object, into XML.

Our final XML will look something like:

 Rohan Daye  9911034731 9911033478   Name1 City1   Name2 City2  

Notice that our phone numbers are encapsulated in a phoneNumbers wrapper while our address is not.

We can express this nuance via the @JacksonXMLElementWrapper annotation in our Person class:

public final class Person { private String firstName; private String lastName; private List phoneNumbers = new ArrayList(); @JacksonXmlElementWrapper(useWrapping = false) private List address = new ArrayList(); //standard setters and getters }

Actually, we can change the wrapping element name with @JacksonXmlElementWrapper(localName = ‘phoneNumbers'). Or, if we don't want to wrap our elements, we can disable the mapping with @JacksonXmlElementWrapper(useWrapping = false).

And then let's define our Address type:

public class Address { String streetName; String city; //standard setters and getters }

Jackson mengurus sisanya untuk kami. Seperti sebelumnya, kita cukup memanggil writeValue lagi:

private static final String XML = "..."; @Test public void whenJavaSerializedToXmlFile_thenSuccess() throws IOException { XmlMapper xmlMapper = new XmlMapper(); Person person = testPerson(); // test data ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); xmlMapper.writeValue(byteArrayOutputStream, person); assertEquals(XML, byteArrayOutputStream.toString()); }

7. Deserialize XML ke List

Jackson juga dapat membaca XML yang berisi daftar objek.

Jika kita mengambil XML yang sama seperti sebelumnya, metode readValue sudah cukup:

@Test public void whenJavaDeserializedFromXmlFile_thenCorrect() throws IOException { XmlMapper xmlMapper = new XmlMapper(); Person value = xmlMapper.readValue(XML, Person.class); assertEquals("City1", value.getAddress().get(0).getCity()); assertEquals("City2", value.getAddress().get(1).getCity()); }

8. Kesimpulan

Artikel sederhana ini mengilustrasikan cara membuat POJO sederhana menjadi XML dan mendapatkan POJO dari data XML dasar.

Kami juga telah mempelajari cara membuat serial dan deserialisasi kacang kompleks yang berisi koleksi.

Kode sumber yang menyertai artikel ini tersedia di GitHub.