[英]Custom Xstream/JSON converter for enum
I have the following Enum
: 我有以下
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;
}
}
I am trying to write an XStream Converter
that will know to map back a JSON element " mystate
" to a MyState
instance. 我正在尝试编写一个XStream
Converter
,它将知道将JSON元素“ mystate
”映射回MyState
实例。
"someJson": {
"object1": {
"mystate": closed
}
}
This should produce, amongst other objects ( someJson
and object1
) a MyState.Close
instance. 除了其他对象(
someJson
和object1
)之外,这MyState.Close
产生MyState.Close
实例。 I've started the Converter
, but haven't gotten very far: 我已经启动了
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
}
}
Then, to create the mapper and use it: 然后,创建映射器并使用它:
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());
How can I implement marshal
and unmarshal
so thatI get the desired mapping? 我怎样才能实现
marshal
和unmarshal
这样thatI获得所需的映射? Thanks in advance! 提前致谢!
You can accomplish this by doing 2 things: 您可以通过执行以下两项操作来完成此操作:
toString()
override to your enum ( MyStateEnum
); MyStateEnum
)添加一个查找方法以及一个toString()
重写; and AbstractSingleValueConverter
instead of implementing Converter
AbstractSingleValueConverter
而不是实现Converter
MyStateEnum
: 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
: 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);
}
}
By adding getMyStateByDesc(String)
to your enum, you now have a way to look up all the various enumerated values from the outside, by providing a desc
string. 通过将
getMyStateByDesc(String)
添加到您的枚举中,您现在可以通过提供desc
字符串,从外部查找所有各种枚举值。 The MyStateEnumConverter
(which extends AbstractSingleValueConverter
) uses your toString()
override under the hood to associate a MyStateEnum
instance with a text string. MyStateEnumConverter
(扩展了AbstractSingleValueConverter
)在MyStateEnumConverter
使用您的toString()
重写将MyStateEnum
实例与文本字符串相关联。
So when XStream is parsing the JSON, it sees a JSON object of, say, "opened", and this new converter knows to pass "opened" into the converter's fromString(String)
method, which in turn uses getMyStateByDesc(String)
to lookup the appropriate enum instance. 因此,当XStream解析JSON时,它会看到一个JSON对象,例如“ opened”,并且此新转换器知道将“ opened”传递到转换器的
fromString(String)
方法中,该方法又使用getMyStateByDesc(String)
进行查找。适当的枚举实例。
Don't forget to register your converter with your XStream
instance as you already showed in your original question. 别忘了像原始问题中已经显示的那样,将转换器注册到
XStream
实例中。
You can use the EnumToStringConverter 您可以使用EnumToStringConverter
Example 例
@XStreamConverter(EnumToStringConverter.class)
public enum MyStateEnum {
enter code here
...
Use xstream.autodetectAnnotations(true) 使用xstream.autodetectAnnotations(true)
Why are you using xstream for json support? 为什么将xstream用于json支持? You have a couple of other libraries specialized in json and that do it well.
您还有几个专门用于json的其他库,它们做得很好。 Also closed without quotes is not valid json.
也关闭不带引号的无效json。
Try for example Genson , it will work out of the box. 例如尝试Genson ,它将立即可用 。 The values in the json stream would be "Close", "Indeterminate", etc and when deserializing it will produce the correct enum.
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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.