C# で記述されたサービスと通信する必要がある JSON REST クライアント アプリケーションを作成しています。日付の違いなどのほとんどは、FlexJson ライブラリを使用すると簡単に解決できます。
ただし、そうでないことが 1 つあります。サービスから受信した値である整数として送信される Enum 値であり、Java Enum 値にマップする必要があります。
Java 列挙型は問題ありません。もちろん、値が存在する限り、整数を列挙型に変換できます。しかし、Flexjson を取得して値を変換することはできません。
列挙型の 1 つはFormStateと呼ばれます
カスタム Transformer を作成しました。それをOurEnumTransformerと呼びましょう。これは、AbstractTransformer を拡張し、ObjectFactory を実装します。逆シリアル化時に.use(Enum.class, OurEnumTransformer)を追加します。そうしないと、次のようなエラーが発生します。
4 を FormState の列挙定数に変換する方法がわかりません
これは整数であり、列挙値の名前ではないため意味があります
しかし、逆シリアル化でエラーが発生し続ける.use(...)を追加します。
FormState には、引数のないコンストラクターがありません。Flexjson は、保護された、プライベート、またはパブリックの引数のないコンストラクターをインスタンス化します。
しかし、実際には、パラメーターのないプライベート コンストラクターがあります。
もう 1 つのことは、OurEnumTransformer に設定されたブレークポイントがヒットしないことです。
.use(Enum.class, OurEnumTransformer)が整数値を持つ列挙型で機能しない理由を教えてください。
以下の列挙型と OurEnumTransformeris のコード
public enum FormState {
None(0),
EditMode(1),
SignedBySender(2),
AddedToRide(4),
SignedByTransporter(8),
SignedByReceiver(16),
DLT_UNKNOWN();
private int value;
private FormState() {
this.value= -1;
}
private FormState(int value) {
this.value= value;
}
public int getValue()
{
return value;
}
private static final Map<Integer, FormState> intToTypeMap = new HashMap<Integer, FormState>();
static
{
for(FormState type: FormState.values())
{
intToTypeMap.put(type.value, type);
}
}
public static FormState fromInt(int i) {
FormState type = intToTypeMap.get(Integer.valueOf(i));
if (type == null)
return FormState.DLT_UNKNOWN;
return type;
}
}
そして工場
public final class OurEnumTransformer extends AbstractTransformer implements
ObjectFactory {
@SuppressWarnings("rawtypes")
@Override
public Object instantiate(ObjectBinder context, Object value, Type targetType,
Class targetClass)
{
if(targetClass.equals(FormState.class))
return FormState.fromInt((Integer)value);
else if(targetClass.equals(TrajectState.class))
return TrajectState.fromInt((Integer)value);
else
throw new JSONException(String.format("%s: Don't know how to convert %s to enumerated constant of %s",
context.getCurrentPath(), value, targetType));
}
@Override
public void transform(Object arg0) {
// TODO Auto-generated method stub
}
}
最後に呼び出しコード:
List<JsonTrajectModel> result = null;
JSONDeserializer<List<JsonTrajectModel>> deser = new JSONDeserializer<List<JsonTrajectModel>>();
result = deser
.use(Date.class, dateTransformer)
.use("values", JsonTrajectModel.class)
.use(Enum.class, enumTransformer)
.deserialize(jsonData);
最後のコード ブロックでは、jsonData は有効な JSON 文字列であり、enumTransformer は OurEnumTransformer インスタンスです。
最後に、このコードで使用されている dateTransformer は機能します。
どんな助けでも大歓迎です。