1. 概要

以前の記事では、XStreamを使用してJavaオブジェクトをXMLにシリアル化する方法を学びました。 このチュートリアルでは、逆の方法、つまりXMLをJavaオブジェクトに逆シリアル化する方法を学習します。 これらのタスクは、注釈を使用して、またはプログラムで実行できます。

XStreamとその依存関係を設定するための基本的な要件については、前の記事を参照してください。

2. XMLからオブジェクトを逆シリアル化する

まず、次のXMLがあるとします。

<com.baeldung.pojo.Customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 03:46:16.381 UTC</dob>
</com.baeldung.pojo.Customer>

これをJavaCustomerオブジェクトに変換する必要があります。

public class Customer {
 
    private String firstName;
    private String lastName;
    private Date dob;
 
    // standard setters and getters
}

XMLは、 File InputStream Reader String など、さまざまな方法で入力できます。 簡単にするために、上記のXMLがStringオブジェクトにあると仮定します。

Customer convertedCustomer = (Customer) xstream.fromXML(customerXmlString);
Assert.assertTrue(convertedCustomer.getFirstName().equals("John"));

3. セキュリティの側面

XStreamは文書化されていないJava機能とJavaReflectionを使用するため、任意のコード実行またはリモートコマンド実行攻撃に対して脆弱である可能性があります。

セキュリティに関する詳細な考慮事項はこのチュートリアルの範囲外ですが、脅威を説明する専用の記事があります。 また、XStreamの公式ページもチェックする価値があります。

チュートリアルの目的上、すべてのクラスが「安全」であると仮定しましょう。 したがって、XStreamを構成する必要があります。

XStream xstream = new XStream();
xstream.allowTypesByWildcard(new String[]{"com.baeldung.**"});

4. エイリアス

最初の例では、XMLの最も外側のXMLタグにクラスの完全修飾名があり、Customerクラスの場所と一致しています。 この設定により、XStreamは追加の構成なしでXMLをオブジェクトに簡単に変換します。 しかし、私たちは常にこれらの条件を持っているとは限りません。 XMLタグの命名を制御できない場合や、フィールドのエイリアスを追加する場合があります。

たとえば、外部タグに完全修飾クラス名を使用しないようにXMLを変更したとします。

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 03:46:16.381 UTC</dob>
</customer>

エイリアスを作成することで、このXMLを隠すことができます。

4.1. クラスエイリアス

プログラムで、またはアノテーションを使用して、エイリアスをXStreamインスタンスに登録します。 Customerクラスに@XStreamAliasで注釈を付けることができます。

@XStreamAlias("customer")
public class Customer {
    //...
}

次に、このアノテーションを使用するようにXStreamインスタンスを構成する必要があります。

xstream.processAnnotations(Customer.class);

または、プログラムでエイリアスを設定する場合は、次のコードを使用できます。

xstream.alias("customer", Customer.class);

4.2. フィールドエイリアス

次のXMLがあるとします。

<customer>
    <fn>John</fn>
    <lastName>Doe</lastName>
    <dob>1986-02-14 03:46:16.381 UTC</dob>
</customer>

fn タグは、 Customer オブジェクトのどのフィールドとも一致しないため、逆シリアル化する場合は、そのフィールドのエイリアスを定義する必要があります。 これは、次のアノテーションを使用して実現できます。

@XStreamAlias("fn")
private String firstName;

または、プログラムで同じ目標を達成することもできます。

xstream.aliasField("fn", Customer.class, "firstName");

5. 暗黙のコレクション

ContactDetailsの単純なリストを含む次のXMLがあるとします。

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 04:14:20.541 UTC</dob>
    <ContactDetails>
        <mobile>6673543265</mobile>
        <landline>0124-2460311</landline>
    </ContactDetails>
    <ContactDetails>...</ContactDetails>
</customer>

のリストをロードしたい ContactDetailsリスト Javaオブジェクトのフィールド。 これは、次のアノテーションを使用して実現できます。

@XStreamImplicit
private List<ContactDetails> contactDetailsList;

または、プログラムで同じ目標を達成することもできます。

xstream.addImplicitCollection(Customer.class, "contactDetailsList");

6. フィールドを無視する

次のXMLがあるとしましょう。

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 04:14:20.541 UTC</dob>
    <fullName>John Doe</fullName>
</customer>

上記のXMLには、追加の要素がありますこれはJavaにありませんお客様物体。

余分な要素を気にせずに上記のxmlを逆シリアル化しようとすると、プログラムはUnknownFieldExceptionをスローします。

No such field com.baeldung.pojo.Customer.fullName

例外が明確に述べているように、XStreamはフィールドfullNameを認識しません。

この問題を克服するには、未知の要素を無視するように構成する必要があります。

xstream.ignoreUnknownElements();

7. 属性フィールド

オブジェクトのフィールドとして逆シリアル化する要素の一部として属性を持つXMLがあるとします。 contactType属性をContactDetailsオブジェクトに追加します。

<ContactDetails contactType="Office">
    <mobile>6673543265</mobile>
    <landline>0124-2460311</landline>
</ContactDetails>

contactType XML属性を逆シリアル化する場合は、表示するフィールドで@XStreamAsAttributeアノテーションを使用できます。

@XStreamAsAttribute
private String contactType;

または、プログラムで同じ目標を達成することもできます。

xstream.useAttributeFor(ContactDetails.class, "contactType");

8. 結論

この記事では、XStreamを使用してXMLをJavaオブジェクトに逆シリアル化するときに使用できるオプションについて説明しました。

この記事の完全なソースコードは、リンクされたGitHubリポジトリからダウンロードできます。