我有以下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;
}
}
我正在尝试编写一个XStream Converter
,它将知道将JSON元素“mystate
”映射回MyState
实例。
"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());
如何实施marshal
和unmarshal
以便获得所需的映射?提前谢谢!
答案 0 :(得分:3)
你可以通过做两件事来做到这一点:
toString()
)添加查找方法和MyStateEnum
覆盖;和AbstractSingleValueConverter
而非实施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
字符串从外部查找所有各种枚举值。 MyStateEnumConverter
(扩展AbstractSingleValueConverter
)使用您的toString()
覆盖,将MyStateEnum
实例与文本字符串相关联。
因此,当XStream解析JSON时,它会看到一个JSON对象,例如“打开”,这个新的转换器知道将“打开”传递给转换器的fromString(String)
方法,后者又使用{{ 1}}查找相应的枚举实例。
不要忘记在原始问题中显示的getMyStateByDesc(String)
实例中注册您的转换器。
答案 1 :(得分:0)
您可以使用EnumToStringConverter
实施例
@XStreamConverter(EnumToStringConverter.class)
public enum MyStateEnum {
enter code here
...
使用xstream.autodetectAnnotations(true)
答案 2 :(得分:-2)
为什么使用xstream支持json?你有几个专门用于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());