No enum const classと怒られてしまい、うまくいきませんでした。
flex 側で IExternalizable を実装して String を投げるようにしてみたのですが、そうすると今度は BlazeDS 側で配列に変更しようとしてエラーで落ちました。
方法が間違っていたのかもしれませんが、どうも解決法が見つけられなかったので、とりあえずはワークアラウンドで対応することにしました。
(´・ω・`) 正規の方法を教えてください、、、
4.21.2010追記:正規の方法がありました。詳細はこちらを参照のこと。
workaround
ActionScript 側の Enum (のような)実装では、内部に必ず Enum.valueOf() メソッドの第二引数に対応する文字列を持つpublicなインスタンス変数(or getter/setter)を配置する。ActionScript 側の Enum (のような)実装では、必ず public var name:String を定義し、java 側の Enum#getName() と対応させる。
それ以外の変数(or getter/setter)を配置してもよいが、すべてメタタグ [Transient] をつける。BlazeDS4のソースにパッチを当てる。
この方法だと、副作用として flex 側で IExternalizable を実装する必要がないのでラクチンです。
パッチ
対象のソースコードは、flex.messaging.io.amf.translator.decoder.EnumDecoder クラスです。
元のコードは以下のようになっています。
55: Enum value = Enum.valueOf(desiredClass, encodedObject.toString());
encodedObject の型が flex.messaging.io.amf.ASObject 型なので、encodedObject.toString() の値は以下のようなフォーマットの文字列に変換されます。
ASObject(33469162){name=HOGE}
上記のワークアラウンドを適用すると、ASObjectはひとつだけエントリを持つマップとなるはずなので、そのエントリの値を使えば Enum が復元できます。
以下が変更内容です。ASObject以外が来る場合もあるかもしれないので(まだそこまでソースを追ってません)一応、オリジナルのコードも残しておきます。
final Enum value; if (ASObject.class.isInstance(encodedObject)) { // patch for workaround value = Enum.valueOf(desiredClass, ASObject.class.cast(encodedObject).values().iterator().next().toString()); } else { // original value = Enum.valueOf(desiredClass, encodedObject.toString()); }
ActionScript 側のEnum(のようなもの)の例
public final class Hoge { public var name:String; public function Hoge(name:String) { this.name = name; } public static const HOGETAROU:Hoge = new Hoge("HOGETAROU"); public static const HOGEJIROU:Hoge = new Hoge("HOGEJIROU"); public static const HOGENOSUKE:Hoge = new Hoge("HOGENOSUKE"); }
0 件のコメント:
コメントを投稿