Serialisasi dan Deserialisasi XML dengan Jackson

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melihat cara menyusun objek Java ke data XML menggunakan Jackson 2.x dan mendeseralisasikannya kembali ke POJO .

Kami akan memfokus pada operasi asas yang tidak memerlukan banyak kerumitan atau penyesuaian.

2. Objek XmlMapper

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

XmlMapper mapper = new XmlMapper();

Ini mapper terdapat di jackson-dataformat-xml jar, jadi kami perlu menambah ia sebagai pergantungan kepada kami pom.xml :

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

Sila periksa versi terbaru ketergantungan jackson-dataformat-xml di repositori Maven.

3. Serialisasi Java ke XML

XmlMapper adalah subkelas ObjectMapper yang digunakan dalam serialisasi JSON. Walau bagaimanapun, ia menambah beberapa perubahan khas XML ke kelas induk.

Kita sekarang dapat melihat bagaimana menggunakannya untuk melakukan siriisasi sebenar. Mari buat kelas Java terlebih dahulu:

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

3.1. Serial ke String XML

Kita dapat menyusun objek Java kita ke dalam String XML :

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

Hasilnya kita akan mendapat:

 1 2 

3.2. Bersiri ke Fail XML

Kami juga dapat menyusun 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 dapat melihat kandungan fail yang dihasilkan bernama simple_bean.xml :

 1 2 

4. Deserialize XML ke Java

Di bahagian ini, kita akan melihat bagaimana mendapatkan objek Java dari XML.

4.1. Deserialize Dari Rentetan XML

Seperti serialisasi, kita juga dapat mendeserialisasikan String XML 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. Nyahpusatkan Dari Fail XML

Begitu juga, jika kita mempunyai fail XML, kita dapat mengubahnya kembali ke objek Java.

Di sini, pertama-tama kita membaca fail menjadi aliran input dan kemudian menukar aliran input ke String dengan kaedah utiliti yang mudah.

Selebihnya kod serupa dengan yang terdapat di bahagian 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); }

Kaedah utiliti:

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. Mengendalikan Elemen Bermodalkan

Pada bahagian ini, kita akan melihat bagaimana menangani senario di mana kita mempunyai XML dengan elemen kapitalisasi untuk deserialisasi atau kita perlu membuat siri objek Java ke XML dengan satu atau lebih elemen yang ditulis huruf besar.

5.1. Deserialize Dari Rentetan XML

Katakan kita mempunyai XML dengan satu bidang yang ditulis dengan huruf besar:

 1 2 

Untuk menangani elemen huruf besar dengan betul, kita perlu memberi anotasi bidang "x" dengan anotasi @JsonProperty :

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

Kita sekarang dapat mendeseralisasikan String XML 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. Serial ke String XML

Dengan memberi anotasi bidang yang diperlukan dengan @JsonProperty, kita dapat menyusun objek Java dengan betul ke dalam String XML dengan satu atau lebih elemen yang dimodalkan:

@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. cerita bersambung Senarai untuk XML

The XmlMapper mampu cerita bersambung keseluruhan kacang Java dalam sebuah dokumen. Untuk menukar objek Java ke XML, kami akan mengambil contoh mudah dengan objek dan tatasusunan 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 menjaga selebihnya untuk kita. Seperti sebelumnya, kita boleh 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. Nyahsenaraikan XML ke Senarai

Jackson juga dapat membaca XML yang mengandungi senarai objek.

Sekiranya kita menggunakan XML yang sama seperti sebelumnya, kaedah readValue adalah baik:

@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. Kesimpulannya

Artikel ringkas ini menggambarkan cara membuat siri POJO sederhana ke XML dan mendapatkan POJO dari data asas XML.

Kami juga telah meneliti bagaimana untuk membuat siri dan menyah deserialisasi kacang polong yang mengandungi koleksi.

Kod sumber yang menyertai artikel ini terdapat di GitHub.