Java 用于枚举的自定义Xstream/JSON转换器
我有以下Java 用于枚举的自定义Xstream/JSON转换器,java,json,enums,xstream,oxm,Java,Json,Enums,Xstream,Oxm,我有以下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;
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;
}
}
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();
}
}
我正在尝试编写一个XStream,它将知道如何将JSON元素“mystate
”映射回一个mystate
实例
"someJson": {
"object1": {
"mystate": closed
}
}
这将在其他对象(someJson
和object1
)中生成一个MyState.Close
实例。我已经启动了转换器
,但还没有走多远:
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
以获得所需的映射?提前谢谢 为什么要使用xstream来支持json?您还有其他几个专门用于json的库,它们做得很好。也不带引号的closed不是有效的json
例如,尝试一下,它将开箱即用。
json流中的值将是“Close”、“Undeterminate”等,反序列化时将生成正确的枚举
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());
为什么要使用xstream来支持json?您还有其他几个专门用于json的库,它们做得很好。也不带引号的closed不是有效的json 例如,尝试一下,它将开箱即用。 json流中的值将是“Close”、“Undeterminate”等,反序列化时将生成正确的枚举
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());
您可以通过做两件事来实现这一点:
toString()
覆盖添加到枚举(mystatenum
);及AbstractSingleValueConverter
而不是实现Converter
mystatenum
:
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;
}
}
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)
来查找适当的枚举实例
"someJson": {
"object1": {
"mystate": closed
}
}
不要忘了向您的
XStream
实例注册转换器,正如您在原始问题中所示。您可以通过做两件事来完成这一点:
toString()
覆盖添加到枚举(mystatenum
);及AbstractSingleValueConverter
而不是实现Converter
mystatenum
:
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;
}
}
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)
来查找适当的枚举实例
"someJson": {
"object1": {
"mystate": closed
}
}
不要忘记向您的
XStream
实例注册转换器,正如您在原始问题中所显示的那样。您可以使用EnumToString converter
范例
@XStreamConverter(EnumToStringConverter.class)
public enum MyStateEnum {
enter code here
...
使用xstream.autodetectanotations(true)您可以使用EnumToStringConverter 范例
@XStreamConverter(EnumToStringConverter.class)
public enum MyStateEnum {
enter code here
...
使用xstream.autodetectAnnotations(true)正确回答错误的问题-我只是对xstream感兴趣,谁的
JettisonMappedXmlDriver
非常适合JSON。正确回答错误的问题-我只对xstream感兴趣,谁的JettisonMappedXmlDriver
非常适合JSON。