1

私は次のものを持っていますEnum

public enum MyState {
    Open("opened"),
    Close("closed"),
    Indeterminate("unknown");

    private String desc;

    private MyState(String desc) {
        setDesc(desc);
    }

    public String getDesc() {
        return this.desc;
    }

    private void setDesc(String desc) {
        this.desc = desc;
    }
}

JSON要素" "をインスタンスConverterにマップバックすることを認識しているXStreamを作成しようとしています。mystateMyState

"someJson": {
    "object1": {
        "mystate": closed
    }
}

これにより、他のオブジェクト(someJsonおよびobject1)の中でも特にMyState.Closeインスタンスが生成されます。私は始めましたがConverter、それほど遠くまでは行きませんでした:

public class MyStateEnumConverter implement Converter {
    @Override
    public boolean canConvert(Class clazz) {
        return clazz.equals(MyState.class);
    }

    @Override
    public void marshal(Object value, HierarchialStreamWriter writer, MarshallingContext context) {
        ??? - no clue here
    }

    @Override
    public Object unmarshal(HierarchialStreamReader reader, UnmarshallingContext context) {
        ??? - no clue here
    }
}

次に、マッパーを作成して使用するには、次のようにします。

XStream mapper = new XStream(new JettisonMappedXmlDriver());
mapper.registerConverter(new MyStateEnumConverter);

SomeJson jsonObj = mapper.fromXML(jsonString);

// Should print "closed"
System.out.println(jsonObject.getObject1().getMyState().getDesc());

どうすれば実装できmarshalunmarshal目的のマッピングを取得できますか?前もって感謝します!

4

3 に答える 3

3

これは、次の2つのことで実現できます。

  1. ルックアップメソッドとtoString()オーバーライドを列挙型に追加します(MyStateEnum); と
  2. AbstractSingleValueConverter実装する代わりにXStreamを拡張するConverter

MyStateEnum

public enum MyStateEnum {
    // Everything you had is fine

    // But now, add:
    public static MyStateEnum getMyStateByDesc(String desc) {
        for(MyStateEnum myState : MyStateEnum.values())
            if(myState.getDesc().equals(desc))
                return myState;

        return null;
    }

    @Override
    public String toString() {
        return getDesc();
    }
}

MyStateEnumConverter

public class MyStateEnumConverter extends AbstractSingleValueConverter {
    @Override
    public boolean canConvert(Class clazz) {
        return clazz.equals(MyStateEnum.class);
    }

    @Override
    public Object fromString(String parsedText) {
        return MyStateEnum.getMyStateByDesc(parsedText);
    }
}

列挙型に追加getMyStateByDesc(String)することで、文字列を提供することにより、列挙されたさまざまな値をすべて外部から検索する方法が得られdescます。(MyStateEnumConverterextends AbstractSingleValueConverter)は、toString()内部でオーバーライドを使用して、MyStateEnumインスタンスをテキスト文字列に関連付けます。

したがって、XStreamがJSONを解析しているとき、たとえば「opened」のJSONオブジェクトが表示され、この新しいコンバーターは「opened」をコンバーターのfromString(String)メソッドに渡すことを認識します。このメソッドはgetMyStateByDesc(String)、適切な列挙型インスタンスを検索するために使用します。

XStream元の質問ですでに示したように、コンバーターをインスタンスに登録することを忘れないでください。

于 2013-01-23T16:44:34.543 に答える
0

EnumToStringConverterを使用できます

ドキュメンテーション

@XStreamConverter(EnumToStringConverter.class)
public enum MyStateEnum {
enter code here

...

xstream.autodetectAnnotations(true)を使用する

于 2014-05-21T14:31:07.837 に答える
-2

なぜjsonサポートにxstreamを使用しているのですか?jsonに特化した他のライブラリがいくつかあり、それはうまく機能します。また、引用符なしで閉じた場合、有効なjsonではありません。

たとえばGensonを試してみてください、それは箱から出して動作します。jsonストリームの値は、「Close」、「Indeterminate」などになり、逆シリアル化すると正しい列挙型が生成されます。

class SomeObject {
   private MyState state;
   ...
}

Genson genson = new Genson();
// json = {"state" : "Indeterminate"}
String json = genson.serialize(new SomeObject(MyState.Indeterminate));

// deserialize back
SomeObject someObject = genson.deserialize(json, SomeObject.class);

// will print unknown
System.out.println(someObject.getDesc());
于 2013-01-11T18:42:16.873 に答える