Jacksonを使ったXMLからJSONへの変換

Jacksonを使用してXMLをJSONに変換する

1. 概要

このチュートリアルでは、Jacksonを使用してXMLメッセージをJSONに変換する方法を説明します。

ジャクソンを初めて使用する読者は、最初にthe basicsに慣れることを検討してください。

2. ジャクソンの紹介

ジャクソンでは、JSONを3つの異なる方法で解析することを考えることができます。

  • 最初で最も一般的なのは、ObjectMapperを使用したデータバインディングです。

  • 2つ目は、TreeTraversingParserJsonNodeを使用したツリーデータ構造へのマッピングです。

  • 3つ目は、JsonParserJsonGeneratorを使用して、トークンごとにツリーデータ構造をストリーミングすることです。

現在、JacksonはXMLデータの最初の2つもサポートしています。 そのため、Jacksonが1つの形式から別の形式への変換をどのように支援できるかを見てみましょう。

3. 依存関係

まず、pom.xmljackson-databindの依存関係を追加する必要があります。


    com.fasterxml.jackson.core
    jackson-databind
    2.9.7

このライブラリにより、データバインディングAPIを使用できるようになります。

2つ目は、JacksonのXMLサポートを追加するjackson-dataformat-xmlです。


    com.fasterxml.jackson.dataformat
    jackson-dataformat-xml
    2.9.7

4. データバインディング

簡単に言うと、データバインディングは、シリアル化されたデータをJavaオブジェクトに直接マップする場合です。

これを調べるには、let’s define our XML with Flower and Color properties


    Poppy
    RED
    9

これは、次のJava表記に似ています。

public class Flower {
    private String name;
    private Color color;
    private Integer petals;
    // getters and setters
}

public enum Color { PINK, BLUE, YELLOW, RED; }

Our first step will be to parse the XML into a Flower instance。 これを行うには、XmlMapperのインスタンスを作成します。これはObjectMapperに相当するJacksonのXMLであり、そのreadValue メソッドを使用します。

XmlMapper xmlMapper = new XmlMapper();
Flower poppy = xmlMapper.readValue(xml, Flower.class);

Flowerインスタンスを取得したら、使い慣れたObjectMapperを使用してJSONとして書き出す必要があります。

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(poppy);

そして、結果として、JSONに相当するものを取得します。

{
    "name":"Poppy",
    "color":"RED",
    "petals":9
}

5. ツリートラバーサル

中間クラスを維持したくない場合や、構造の一部のみを変換したい場合など、ツリー構造を直接確認すると、柔軟性が向上する場合があります。

ただし、後で説明するように、いくつかのトレードオフがあります。

最初のステップは、データバインディングを使用する場合の最初のステップに似ています。 ただし、今回はreadTreeメソッドを使用します。

XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xml.getBytes());

これを行うと、予想どおり、name, color,petalsの3つの子を持つJsonNodeが作成されます。

次に、JsonNode を代わりに送信するだけで、再びObjectMapperを使用できます。

ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);

さて、結果は最後の例とは少し異なります。

{
    "name":"Poppy",
    "color":"RED",
    "petals":"9"
}

注意深く調べると、花びらの属性が数字ではなく文字列にシリアル化されていることがわかります。  これは、readTreeが明示的な定義なしにデータ型を推測しないためです。

5.1. 制限事項

また、JacksonのXMLツリートラバーサルサポートには特定の制限があります。

  • Jackson cannot differentiate between an Object and an Array. XMLにはオブジェクトをオブジェクトのリストから区別するためのネイティブ構造がないため、Jacksonは繰り返される要素を単一の値に照合するだけです。

  • また、Jacksonは各XML要素をJSONノードにマッピングする必要があるため、混合コンテンツをサポートしていません。

6. メモリの制約

Now, both of these have the notable downside that the entire XML needs to be in memory at once in order to perform the conversion.ジャクソンがツリー構造のトークンとしてのストリーミングをサポートするまで、この制約に固執するか、XMLStreamReader.のようなもので自分自身をローリングすることを検討する必要があります

7. 結論

このチュートリアルでは、JacksonがXMLデータを読み取ってJSONに書き込むさまざまな方法を簡単に学びました。 また、サポートされている各アプローチの制限を簡単に確認しました。

いつものように、チュートリアルに付属する完全なソースコードはover on GitHubで入手できます。