从 JSON 反序列化 java 枚举
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18505102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Deserialize java enum from JSON
提问by chetan
We use Hymanson 1.9.1 to serialize and deserialize JSON request response strings to/from Java objects. Primitive Java types, collection types, and custom objects are (de)serialized without issues. However, I have a problem trying to deserialize JSON string into java enum. JSON string is serialized like so:
我们使用 Hymanson 1.9.1 来序列化和反序列化 Java 对象的 JSON 请求响应字符串。原始 Java 类型、集合类型和自定义对象被(反)序列化没有问题。但是,我在尝试将 JSON 字符串反序列化为 java 枚举时遇到问题。JSON 字符串序列化如下:
"wt":{"wt":100.5,"unit":{"LBS":3}}
Java type for wt is like so:
wt 的 Java 类型如下所示:
public class Weight {
protected double weight;
protected Unit unit;
}
I referred to this, this, and thison SO and came up with enum for weight units like so:
我在 SO 上提到了this、this和this,并提出了重量单位的枚举,如下所示:
public enum Unit {
KG("kg"),
GM("gm"),
LBS("lbs"),
OZ("oz");
private String value;
private WeightMeasurementUnit(String value) { this.value = value; }
@JsonValue
public String getValue() { return this.value; }
@JsonCreator
public static Unit create(String val) {
Unit[] units = Unit.values();
for (Unit unit : units) {
if (unit.getValue().equals(val)) {
return unit;
}
}
return LBS;
}
}
The problem is, when ever I try to deserialize above mentioned JSON I get this error saying: "Unrecognized field "LBS" (Class a.b.c.d.Weight), not marked as ignorable" Exception stacktrace is like so:
问题是,当我尝试反序列化上述 JSON 时,我收到此错误消息:“无法识别的字段“LBS”(类 abcdWeight),未标记为可忽略的异常堆栈跟踪如下所示:
Caused by: org.codehaus.Hymanson.map.exc.UnrecognizedPropertyException: Unrecognized field "LBS" (Class a.b.c.d.Weight), not marked as ignorable
at [Source: java.io.ByteArrayInputStream@20172017; line: 1, column: 464] (through reference chain: a.b.c.d.MyRequest["blah"]->a.b.c.d.AnotherType["wt"]->a.b.c.d.Weight["LBS"])
at org.codehaus.Hymanson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
at org.codehaus.Hymanson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
at org.codehaus.Hymanson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
at org.codehaus.Hymanson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
at org.codehaus.Hymanson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)
...
...
My questions are: Is the serialized JSON string for enum seem correct ? What else should I include (or annotate) for the enum to be properly deserialized ?
我的问题是: enum 的序列化 JSON 字符串是否正确?为了使枚举正确反序列化,我还应该包括(或注释)什么?
采纳答案by Hari Menon
I am assuming that in the public enum Unit
code block, you mean Unit
instead of WeightMeasurementUnit
.
我假设在public enum Unit
代码块中,您的意思是Unit
而不是WeightMeasurementUnit
.
The Weight
class has only a weight
and a unit
, so if you pass {"wt":100.5,"unit":"lbs"}
, it should work, because a unit
is just a unit without value. So there is no way for the deserializer to parse {"LBS":3}
as a Unit
. What is the 3
for?
这个Weight
类只有 aweight
和 a unit
,所以如果你通过了{"wt":100.5,"unit":"lbs"}
,它应该可以工作,因为 aunit
只是一个没有价值的单位。因此,反序列化器无法解析{"LBS":3}
为Unit
. 是3
为了什么?
Another problem is that your value is "lbs" whereas you are passing "LBS". So either you need to standardise or you need to use unit.getValue().equalsIgnoreCase(val)
另一个问题是您的值是“lbs”,而您传递的是“LBS”。所以要么你需要标准化,要么你需要使用unit.getValue().equalsIgnoreCase(val)
回答by luckyhandler
I would suggest you update your Hymanson version to 2.7.0-rc2 (and probably also before) and then configure the ObjectMapper as follows:
我建议您将 Hymanson 版本更新到 2.7.0-rc2(可能也是之前),然后按如下方式配置 ObjectMapper:
private ObjectMapper createObjectMapper() {
final ObjectMapper mapper = new ObjectMapper();
// enable toString method of enums to return the value to be mapped
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
return mapper;
}
In your enum you just have to override the toString() method:
在您的枚举中,您只需覆盖 toString() 方法:
public enum Unit {
KG,
GM,
LBS,
OZ;
// UPDATE: implicitly already the default so override not needed in this case
@Override
public String toString() {
return name();
}
}
You don't need any annotations or custom deserializers. This would be the way to map a simple enum to a json and vice-versa.
您不需要任何注释或自定义反序列化器。这将是将简单枚举映射到 json 的方法,反之亦然。
If your enum should be mapped from a special string you have to add a value field and a Constructor which assigns this field and return the value in the toString method.
如果您的枚举应该从特殊字符串映射,您必须添加一个值字段和一个构造函数,该构造函数分配此字段并在 toString 方法中返回值。
public enum Unit {
KG("kilogram"),
GM("gram"),
LBS("blah"),
OZ("anything");
Unit(final String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}