52

私は現在、あらゆる種類のオブジェクト (実装を制御できない) を永続化する必要があるプロジェクトに取り組んでいるため、これらのオブジェクトは後で回復できます。

開発時にライブラリのユーザーを制限できないため、ORM を実装できません。

私たちの最初の選択肢は、Java のデフォルトのシリアライゼーションでそれをシリアライズすることでしたが、ユーザーが同じオブジェクトの異なるバージョンを渡し始めたときにオブジェクトを回復するのに多くの問題がありました (属性の型、名前の変更など)。

XMLEncoder クラス (オブジェクトを XML に変換する) を試してみましたが、機能が不足していることがわかりました (たとえば、列挙型をサポートしていません)。

最後に、JAXB も試しましたが、ユーザーはクラスに注釈を付ける必要があります。

良い代替手段はありますか?

4

13 に答える 13

45

それは 2011 年で、商用グレードの REST Web サービス プロジェクトでは、次のシリアライザーを使用してクライアントにさまざまな種類のメディアを提供しています。

  • XStream (XML 用、JSON 用ではない)
  • ジャクソン(JSON 用)
  • Kryo (高速でコンパクトなバイナリ シリアル化形式)
  • Smile (Jackson 1.6 以降に付属するバイナリ形式)。
  • Java オブジェクトのシリアル化。

最近、他のシリアライザーを試しました。

  • SimpleXMLは安定しているように見え、XStream の 2 倍の速度で実行されますが、この状況では構成が少し多すぎます。
  • YamlBeansにはいくつかのバグがありました。
  • SnakeYAMLには、日付に関する小さなバグがありました。

Jackson JSON、Kryo、Jackson Smile はすべて、古き良き Java オブジェクトのシリアル化よりも約 3 倍から 4.5 倍高速でした。XStream は遅い側にあります。しかし、現時点ではこれらはすべて堅実な選択です。残りの 3 つは引き続き監視します。

于 2011-03-14T02:46:20.870 に答える
20

http://x-stream.github.io/いいですね、ぜひ見てみてください!とても便利

于 2008-10-27T07:43:35.367 に答える
16

そのうち、私たちが制御できない実装

解決策はこれを行わないことです。タイプの実装を制御できない場合は、それをシリアル化するべきではありません。物語の終わり。Javaシリアル化は、タイプの異なるバージョン間のシリアル化の非互換性を管理するために、serialVersionUIDを提供します。実装を制御しないと、開発者がクラスを変更したときにIDが正しく変更されていることを確認できません。

「ポイント」の簡単な例を見てみましょう。デカルト座標系または極座標系のいずれかで表すことができます。この種の修正に動的に対処できるシステムを構築することは、法外な費用がかかります。実際には、シリアル化を設計するクラスの開発者である必要があります。

要するに、間違っているのはあなたのデザインであり、テクノロジーではありません。

于 2008-10-27T12:39:10.993 に答える
13

あなたにとって最も簡単なことは、それでもシリアル化、IMOを使用することですが、クラスのシリアル化された形式にもっと考えを入れてください(とにかく本当にやるべきです)。例えば:

  1. SerialUIDを明示的に定義します。
  2. 必要に応じて、独自のシリアル化されたフォームを定義します。

シリアル化されたフォームはクラスのAPIの一部であり、その設計には慎重に検討する必要があります。

私が言ったことのほとんどすべてがEffectiveJavaからのものであるため、詳細については詳しく説明しません。代わりに、それ、特にシリアル化に関する章を参照します。発生しているすべての問題について警告し、問題の適切な解決策を提供します。

http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683


そうは言っても、非シリアル化アプローチをまだ検討している場合は、次の2つがあります。

XMLマーシャリング

多くの人が指摘しているように、オプションはありますが、下位互換性についても同じ問題が発生すると思います。ただし、XMLマーシャリングを使用すると、初期化中に一部のフレームワークがチェックを行う可能性があるため、これらをすぐにキャッチできることを願っています。

YAMLとの間の変換

これは私がいじっていたアイデアですが、YAML形式(少なくともカスタムtoString()形式として)が本当に気に入りました。しかし実際には、唯一の違いは、XMLではなくYAMLにマーシャリングすることです。唯一の利点は、YAMLがXMLよりも人間が読める形式になっていることです。同じ制限が適用されます。

于 2008-10-27T12:23:13.867 に答える
11

Google はバイナリ プロトコルを思いつきました -- http://code.google.com/apis/protocolbuffers/は XML に比べて高速で、ペイロードが小さいです -- 他の人が代替として提案したものです。

プロトコル バッファの利点の 1 つは、C、C++、python、および java と情報を交換できることです。

于 2008-10-28T02:46:35.153 に答える
5

たとえば、 Gsonを使用して json にシリアル化してみてください。

于 2008-10-27T07:45:54.347 に答える
5

また、非常に高速な JDK シリアライゼーションのドロップイン置換: http://ruedigermoeller.github.io/fast-serialization/

于 2012-12-06T22:23:54.233 に答える
1

Betwixtは、オブジェクトをシリアル化するための優れたライブラリですが、自動化されたものにはなりません。シリアル化する必要があるオブジェクトの数が比較的固定されている場合、これは適切なオプションかもしれませんが、「顧客」が常に新しいクラスを投げかける場合は、価値があるよりも多くの労力が必要になる可能性があります (ただし、すべての特殊なケースでは XMLEncoder よりも確実に簡単です)。

もう 1 つのアプローチは、顧客がスローするオブジェクトに対して適切な .betwixt ファイルを提供するよう顧客に要求することです (これにより、実質的に顧客の責任が軽減されます)。

一長一短 - シリアル化は難しい- 完全に脳死のアプローチはありません。Java シリアライゼーションは、私がこれまでに見た中で最も脳死状態のソリューションに近いものですが、バージョン uid 値を誤って使用すると、それが機能しなくなる可能性があります。Java シリアライゼーションでは、マーカー 'Serializable' インターフェイスも使用する必要があるため、ソースを制御できない場合は、そのソースで運が悪いことになります。

あなたが説明したように要件が本当に難しい場合は、オブジェクト/アスペクト/何でも、ある種のBCE(バイトコード変更)に頼る必要があるかもしれません。これは、小さな開発プロジェクトの領域を超えて、Hibernate、Casper、または ORM の領域へと進んでいます....

于 2008-10-28T02:34:14.647 に答える
1

個人的には、Smalltalk (VW と Squeak の両方) および Python との相互運用性を備えているため、Fameをよく使用します。(免責事項、私は Fame プロジェクトの主な貢献者です。)

于 2008-10-27T12:39:23.240 に答える
1

もしかしてキャスター

于 2008-10-27T11:15:37.310 に答える
-1

別のアイデア: キャッシュを使用します。キャッシュは、アプリケーションの制御、スケーラビリティ、および堅牢性を大幅に向上させます。それでもシリアル化する必要がありますが、管理はキャッシング サービス フレームワーク内ではるかに簡単になります。キャッシュは、メモリ、ディスク、データベース、アレイ、またはすべてのオプションに永続化できます。1 つはオーバーフロー、スタンバイ、もう 1 つはフェイルオーバーです。Commons JCS と Ehcache は 2 つの Java 実装であり、後者は最大 32 GB のストレージを無料で使用できるエンタープライズ ソリューションです (免責事項: 私は ehcache の仕事をしていません ;-))。

于 2013-08-10T21:57:06.923 に答える