Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从JSON反序列化java枚举_Java_Json_Enums_Jackson - Fatal编程技术网

从JSON反序列化java枚举

从JSON反序列化java枚举,java,json,enums,jackson,Java,Json,Enums,Jackson,我们使用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 Un

我们使用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;
}
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;
    }
}
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)
我参考了,等等,并提出了重量单位的枚举,如下所示:

public class Weight {

    protected double weight;
    protected Unit unit;
}
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;
    }
}
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时,我都会遇到这样的错误:“未识别的字段”LBS(Class a.b.c.d.Weight),未标记为可忽略”异常stacktrace如下所示:

public class Weight {

    protected double weight;
    protected Unit unit;
}
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;
    }
}
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字符串是否正确?
要正确反序列化枚举,我还应该包括(或注释)哪些内容?

我假设在
公共枚举单元
代码块中,您的意思是
单元
,而不是
权重度量单位

Weight
类只有一个
Weight
和一个
unit
,因此如果你通过
{“wt”:100.5,“unit”:“lbs”}
,它应该可以工作,因为
unit
只是一个没有值的单位。因此,反序列化程序无法将
{“LBS”:3}
作为
单元进行解析。
3
的作用是什么


另一个问题是,你的价值是“磅”,而你是通过“磅”。因此,您要么需要标准化,要么需要使用
unit.getValue().equalsIgnoreCase(val)

我建议您将jackson版本更新为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()方法:

您不需要任何注释或自定义反序列化程序。 这是将简单枚举映射到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;
    }
}

只是猜测-看起来它在序列化时按顺序对枚举字段进行编号,KG=1,GM=2,等等。如果您使用这些数字作为枚举初始值设定项,即使用KG(1),是否有效;总经理(2);磅(3);OZ(4);在枚举单位的定义中?您的问题对我的问题进行了排序。我在寻找注释
@JsonValue
@JsonCreator
。非常正确;在获取值的getValue/OverridentOstring上添加了
@JsonValue
,在匹配EnumName/EnumValue的matchFromString自定义方法上添加了
@JsonCreator
!我认为问题中的字符串是它是如何序列化JSON的——因此无法直接控制更改itRaze2Dust:我的错误。是的,我指的是Unit而不是WeightMeasurementUnit。我对JSON的序列化方式几乎没有控制权。但是,在我可以说JSON序列化错误之前,我想确保我没有对枚举做任何错误。谢谢。@Raze2Dust:这就是问题所在。以这种方式序列化JSON的代码对ObjectMapper使用了错误的映射。我刚刚更改了我的单元枚举以覆盖toString,并在末尾用(at)JsonValuevalue对其进行了注释。单元枚举类中没有定义值