我们使用Jackson 1.9.1来序列化和反序列化进出Java对象的JSON请求响应字符串。原始Java类型、集合类型和自定义对象被(反)序列化,没有问题。但是,我在尝试将JSON字符串反序列化为java枚举时遇到了问题。JSON字符串的序列化方式如下:
"wt":{"wt":100.5,"unit":{"LBS":3}}wt的Java类型如下所示:
public class Weight {
protected double weight;
protected Unit unit;
}我参考了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;
}
}问题是,当我试图反序列化上面提到的JSON时,我得到这样的错误:“无法识别的字段"LBS”(类a.b.c.d.Weight),未标记为可忽略“异常堆栈跟踪是这样的:
Caused by: org.codehaus.jackson.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.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)..。
我的问题是:枚举的序列化JSON字符串是否正确?为了正确地反序列化枚举,我还应该包括(或注释)什么?
发布于 2013-08-29 16:32:25
我假设在public enum Unit代码块中,您指的是Unit而不是WeightMeasurementUnit。
Weight类只有一个weight和一个unit,所以如果您传递{"wt":100.5,"unit":"lbs"},它应该可以工作,因为unit只是一个没有值的单元。因此,反序列化程序无法将{"LBS":3}解析为Unit。3是用来做什么的?
另一个问题是,你的值是"LBS“,而你传递的是"lbs”。所以要么你需要标准化,要么你需要使用unit.getValue().equalsIgnoreCase(val)
发布于 2015-12-23 21:06:07
我建议你更新你的杰克逊版本到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;
}在枚举中,您只需覆盖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();
}
}您不需要任何注释或自定义的反序列化程序。这将是将一个简单的枚举映射到一个json的方法,反之亦然。
如果您的枚举应该从一个特殊字符串映射,则必须添加一个值字段和一个构造函数,该构造函数分配此字段并在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;
}
}https://stackoverflow.com/questions/18505102
复制相似问题