我有以下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
,以便我得到所需的映射?提前感谢!
您可以通过以下两件事来完成:
- 添加查找方法以及
toString()
覆盖到你的enum (MyStateEnum
);和 - 扩展XStream的
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对象,比如"opened",这个新的转换器知道将"opened"传递给转换器的fromString(String)
方法,该方法反过来使用getMyStateByDesc(String)
来查找适当的enum实例。
不要忘记用XStream
实例注册您的转换器,正如您在原始问题中已经显示的那样。
你可以使用EnumToStringConverter
文档例子@XStreamConverter(EnumToStringConverter.class)
public enum MyStateEnum {
enter code here
...
使用xstream.autodetectAnnotations (true)
为什么使用xstream来支持json ?你还有其他一些专门处理json的库,它们做得很好。json.
试试例如Genson,它可以开箱即用。json流中的值将是"Close", "Indeterminate"等,当反序列化时,它将产生正确的enum。
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());