1. 概要

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

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

2. ジャクソンの紹介

Jacksonを使用してJSONを3つの異なる方法で解析することを考えることができます。

  • 最初で最も一般的なのは、ObjectMapperを使用したデータバインディングです。
  • 2つ目は、TreeTraversingParserおよびJsonNodeを使用したツリーデータ構造へのマッピングです。
  • 3つ目は、JsonParserJsonGeneratorを使用して、トークンごとにツリーデータ構造をストリーミングすることです。

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

3. 依存関係

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

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

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

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

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.13.3</version>
</dependency>

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

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

これを調べるために、FlowerプロパティとColorプロパティを使用してXMLを定義しましょう

<Flower>
    <name>Poppy</name>
    <color>RED</color>
    <petals>9</petals>
</Flower>

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

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

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

最初のステップは、XMLをFlowerインスタンスに解析することです。 これを行うには、 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());

これにより、 JsonNode が作成され、予想どおり、名前、色、花びらの3つの子が作成されます。

次に、 ObjectMapper を再度使用して、代わりにJsonNodeを送信できます。

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

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

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

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

5.1. 制限事項

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

  • Jacksonはオブジェクトと配列を区別できません。XMLにはオブジェクトをオブジェクトのリストから区別するためのネイティブ構造がないため、Jacksonは繰り返される要素を単一の値に単純に照合します。
  • また、Jacksonは各XML要素をJSONノードにマップする必要があるため、混合コンテンツをサポートしていません。

これらの理由から、公式のJacksonドキュメントでは、ツリーモデルを使用してXMLを解析しないことを推奨しています

6. メモリの制約

これらの両方に、変換を実行するためにXML全体を一度にメモリに入れる必要があるという顕著な欠点があります。 Jacksonがツリー構造をトークンとしてストリーミングすることをサポートするまで、これに固執します。制約がない場合は、XMLStreamReader。のようなものを使用して独自のローリングを検討する必要があります。

7. 結論

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

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