1

JAXB で生成されたクラスをシリアライズしようとしています。Jettison を使用すると、XML 名前空間を任意の JSON プレフィックスにマッピングするハッシュ マップを作成できます。Jettison を使用すると、シリアライゼーションで大文字と小文字を正しく区別することもできます。JACKSON では、すべて小文字です。つまり、Jettisonの方がXMLRootElement(name=…)はるかによく理解できるようです。

JACKSON が のような JAXB アノテーションをよりよく理解できるようにするにはどうすればよいXMLRootElementですか?

JACKSON に XML→JSON 名前空間マッパーを提供するにはどうすればよいですか?

4

2 に答える 2

2

注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。

EclipseLink MOXy は、JAXB (JSR-222) 準拠の実装です。EclipseLink 2.4.0 では、JSON バインディングが導入されました。MOXy は JAXB 実装であるため、MOXy が生成する JSON 出力は、同じメタデータに基づく XML 出力と非常に一貫性があります。以下に例を挙げて説明します。


ドメインモデル

以下は、この回答に使用するドメイン モデルです。JAXB モデルで名前空間情報を指定する方法の詳細については、http: //blog.bdoughan.com/2010/08/jaxb-namespaces.htmlを参照してください。

パッケージ情報

@XmlSchema(
        namespace="http://www.example.com/A",
        elementFormDefault=XmlNsForm.QUALIFIED,
        xmlns={
                @XmlNs(prefix="a",namespaceURI = "http://www.example.com/A"),
                @XmlNs(prefix="b",namespaceURI = "http://www.example.com/B")
        }
)
package forum13214306;

import javax.xml.bind.annotation.*;

お客様

package forum13214306;

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

    String firstName;

    @XmlElement(namespace="http://www.example.com/B")
    String lastName;

}

XML 処理

以下は、ドメイン モデルが XML 表現にどのように対応するかの例です。

デモ

package forum13214306;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum13214306/input.xml");
        Customer customer = (Customer) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

input.xml/出力

<?xml version="1.0" encoding="UTF-8"?>
<a:customer xmlns:b="http://www.example.com/B" xmlns:a="http://www.example.com/A">
   <a:firstName>Jane</a:firstName>
   <b:lastName>Doe</b:lastName>
</a:customer>

JSON 処理 - 名前空間なし

名前空間は JSON の概念ではないため、回避できる場合はシミュレートしないことをお勧めします。以下では、MOXy がそれらを必要としないことを示します。名前空間を持つ XML ドキュメントに使用されたのとまったく同じドメイン モデルJAXBContextがここで使用されていることに注意してください。

jaxb.properties

MOXy を JSON プロバイダーとして指定するにはjaxb.properties、次のエントリを使用して、ドメイン モデルと同じパッケージで呼び出されるファイルを含める必要があります (参照: http://blog.bdoughan.com/search/label/jaxb.properties )。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

デモ

JSON バインディングを有効にするには、 およびMEDIA_TYPEでプロパティを有効にする必要がMarshallerありUnmarshallerます。

package forum13214306;

import java.io.File;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
        File json = new File("src/forum13214306/input.json");
        Customer customer = (Customer) unmarshaller.unmarshal(json);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.marshal(customer, System.out);
    }

}

input.json/出力

以下は、デモ コードの実行に対する入力と出力です。JSON ドキュメントにシミュレートされた名前空間情報がないことに注意してください。

{
   "customer" : {
      "firstName" : "Jane",
      "lastName" : "Doe"
   }
}

JSON 処理 - シミュレートされた名前空間を使用

デモ

本当に JSON ドキュメントで名前空間をシミュレートしたい場合は、とのNAMESPACE_PREFIX_MAPPERプロパティを利用してそれを行うことができます。MarshallerUnmarshaller

package forum13214306;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Map<String, String> namespaceToPrefixMap = new HashMap<String, String>(2);
        namespaceToPrefixMap.put("http://www.example.com/A", "a");
        namespaceToPrefixMap.put("http://www.example.com/B", "b");

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
        unmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaceToPrefixMap);
        File json = new File("src/forum13214306/input.json");
        Customer customer = (Customer) unmarshaller.unmarshal(json);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaceToPrefixMap);
        marshaller.marshal(customer, System.out);
    }

}

input.json/出力

{
   "a.customer" : {
      "a.firstName" : "Jane",
      "b.lastName" : "Doe"
   }
}

詳細については

于 2012-11-04T11:48:02.230 に答える
0

XML とは異なり、JSON には名前空間がありません。では、なぜ名前空間のマッピングが必要だと思うのでしょうか? データバインディングとは、Java POJO とデータ形式の間のマッピングを、形式の機能を使用して行うことを意味します。XML の場合、これには名前空間、要素と属性の選択などが含まれます。JSON を使用すると、この複雑さの多くが取り除かれます。つまり、プロパティ名がそのまま使用されます。

JAXB アノテーションに関して: Jackson には、より適切な独自のアノテーション セットがありますが、JAXB アノテーションを追加または代替の構成ソースとして使用する場合は、JAXB アノテーション モジュールを使用する必要があります。ただし、使用XMLRootElementに関しては、JSON には不要です。JSON オブジェクトには名前がありません。

「シリアライゼーションで大文字と小文字を正しく区別する」という意味がわかりません-どういう意味ですか?何が問題ですか?POJO 定義の例と予想される JSON を示す必要があります。

最後に、JSON 表記と XML 表記が互いに似ている必要はないことに注意してください。これらは、論理データ モデルが異なるさまざまなデータ形式であり、マッピングも当然異なります。たとえば、JSON では配列とオブジェクトがネイティブに区別されます。一方、XML は両方に要素を使用する必要があります。XML には、JSON にはない名前空間や属性があります。これらは異なる自然なマッピングにつながり、この 2 つを「統一」しようとすると、どちらか一方、または両方がやや不自然な結果になります。Jettison (およびそれを使用するフレームワーク) の場合、醜い JSON (「franken-JSON」) です。

于 2012-11-04T19:48:54.163 に答える